Example #1
0
def coms_test():
    crc_valid = None

    blue_wire_oe_n = Pin('P11', mode=Pin.OUT, pull=Pin.PULL_UP)
    blue_wire_oe_n.value(1)

    uart1 = UART(1, 25000)
    uart1.init(25000, bits=8, parity=None, stop=1)
    tx_buffer_flushed = None
    (data,crc_valid) = ctrl.data_frame(run_crc=True)
    print("Sending: {}\r".format(ubinascii.hexlify(data)),end='\n')
    start_time = time.ticks_us()
    blue_wire_oe_n.value(0)
    t_2_heater = time.ticks_diff(time.ticks_us(), start_time)
    print("t_2_heater {}us OE low".format(t_2_heater))
    start_time = time.ticks_us()
    uart1.write(data)
    tx_buffer_flushed = uart1.wait_tx_done(25)
    t_2_heater = time.ticks_diff(time.ticks_us(), start_time)
    print("t_2_heater {}us Tx".format(t_2_heater))
    start_time = time.ticks_us()
    blue_wire_oe_n.value(1)
    t_2_heater = time.ticks_diff(time.ticks_us(), start_time)
    print("t_2_heater {}us OE high buf flushed{}".format(t_2_heater,tx_buffer_flushed))
    start_time = time.ticks_us()
    num_bytes = uart1.any()
    
    while (num_bytes < 24) :
       num_bytes = uart1.any() 
    t_2_heater = time.ticks_diff(time.ticks_us(), start_time)
    print("t_2_heater {}us to get heater data".format(t_2_heater))
    start_time = time.ticks_us()
    data = util.extractValidFrameFromUART(uart1)
    t_2_heater = time.ticks_diff(time.ticks_us(), start_time)
    print("t_2_heater {}us to extract and load".format(t_2_heater))
    
    print("Halting")
    machine.idle()  
    
    while True:
        pass
class SEN0219_SERIAL:

    # byte mhzCmdReadPPM[9] = {0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79};
    # byte mhzResp[9];    // 9 bytes bytes response
    # byte mhzCmdCalibrateZero[9] = {0xFF,0x01,0x87,0x00,0x00,0x00,0x00,0x00,0x78};
    # byte mhzCmdABCEnable[9] = {0xFF,0x01,0x79,0xA0,0x00,0x00,0x00,0x00,0xE6};
    # byte mhzCmdABCDisable[9] = {0xFF,0x01,0x79,0x00,0x00,0x00,0x00,0x00,0x86};
    # byte mhzCmdReset[9] = {0xFF,0x01,0x8d,0x00,0x00,0x00,0x00,0x00,0x72};

    def __init__(self, TX, RX):
        self.uart = UART(1, 9600, bits=8, parity=None, stop=1, pins=(TX,RX))
        #self.uart.write(b'\xFF\x01\x8D\x00\x00\x00\x00\x00\x72') #Reset

    def deinit(self):
        self.uart.deinit()

    def SEN_Serial_ABCOn(self):
        self.uart.write(b'\xFF\x01\x79\xA0\x00\x00\x00\x00\xE6') #ABC On
        self.uart.wait_tx_done(1000)

    def SEN_Serial_ABCOff(self):
        self.uart.write(b'\xFF\x01\x79\x00\x00\x00\x00\x00\x86') #ABC Off
        self.uart.wait_tx_done(1000)

    def SEN_Serial_read(self):
        self.uart.write(b'\xFF\x01\x86\x00\x00\x00\x00\x00\x79') #get gas command
        self.uart.wait_tx_done(1000)
        Attempts=5
        while(Attempts>0):
            data=self._SerialRead()
            if(data!=False):
                return data
            Attempts-=1
            utime.sleep(1)
        return False

    def _SerialRead(self):
        print(str(self.uart.any()))
        if(self.uart.any()>=9):
            data=self.uart.read(9)
            return data
        else:
            return False
Example #3
0
class Serial:
    def __init__(self,
                 uart_id,
                 baudrate=9600,
                 data_bits=8,
                 stop_bits=1,
                 parity=None,
                 pins=None,
                 ctrl_pin=None):
        self._uart = UART(uart_id, baudrate=baudrate, bits=data_bits, parity=parity, \
                          stop=stop_bits, timeout_chars=2, pins=pins)
        if ctrl_pin is not None:
            self._ctrlPin = Pin(ctrl_pin, mode=Pin.OUT)
        else:
            self._ctrlPin = None

        if baudrate <= 19200:
            self._t35chars = (3500000 *
                              (data_bits + stop_bits + 2)) // baudrate
        else:
            self._t35chars = 1750

    def _calculate_crc16(self, data):
        crc = 0xFFFF

        for char in data:
            crc = (crc >> 8) ^ Const.CRC16_TABLE[((crc) ^ char) & 0xFF]

        return struct.pack('<H', crc)

    def _bytes_to_bool(self, byte_list):
        bool_list = []
        for index, byte in enumerate(byte_list):
            bool_list.extend([bool(byte & (1 << n)) for n in range(8)])

        return bool_list

    def _to_short(self, byte_array, signed=True):
        response_quantity = int(len(byte_array) / 2)
        fmt = '>' + (('h' if signed else 'H') * response_quantity)

        return struct.unpack(fmt, byte_array)

    def _exit_read(self, response):
        if response[1] >= Const.ERROR_BIAS:
            if len(response) < Const.ERROR_RESP_LEN:
                return False
        elif (Const.READ_COILS <= response[1] <= Const.READ_INPUT_REGISTER):
            expected_len = Const.RESPONSE_HDR_LENGTH + 1 + response[
                2] + Const.CRC_LENGTH
            if len(response) < expected_len:
                return False
        elif len(response) < Const.FIXED_RESP_LEN:
            return False

        return True

    def _uart_read(self):
        response = bytearray()

        for x in range(1, 40):
            if self._uart.any():
                response.extend(self._uart.readall())
                # variable length function codes may require multiple reads
                if self._exit_read(response):
                    break
            time.sleep(0.05)

        return response

    def _uart_read_frame(self, timeout=None):
        bytes = bytearray()

        start_ms = time.ticks_ms()
        while timeout == None or time.ticks_diff(start_ms,
                                                 time.ticks_ms()) <= timeout:
            last_byte_ts = time.ticks_us()
            while time.ticks_diff(last_byte_ts,
                                  time.ticks_us()) <= self._t35chars:
                r = self._uart.readall()
                if r != None:
                    bytes.extend(r)
                    last_byte_ts = time.ticks_us()

            if len(bytes) > 0:
                return bytes

        return bytes

    def _send(self, modbus_pdu, slave_addr):
        serial_pdu = bytearray()
        serial_pdu.append(slave_addr)
        serial_pdu.extend(modbus_pdu)

        crc = self._calculate_crc16(serial_pdu)
        serial_pdu.extend(crc)

        if self._ctrlPin:
            self._ctrlPin(1)
        self._uart.write(serial_pdu)
        if self._ctrlPin:
            while not self._uart.wait_tx_done(2):
                machine.idle()
            time.sleep_us(self._t35chars)
            self._ctrlPin(0)

    def _send_receive(self, modbus_pdu, slave_addr, count):
        # flush the Rx FIFO
        self._uart.read()
        self._send(modbus_pdu, slave_addr)
        return self._validate_resp_hdr(self._uart_read(), slave_addr,
                                       modbus_pdu[0], count)

    def _validate_resp_hdr(self, response, slave_addr, function_code, count):

        if len(response) == 0:
            raise OSError('no data received from slave')

        resp_crc = response[-Const.CRC_LENGTH:]
        expected_crc = self._calculate_crc16(response[0:len(response) -
                                                      Const.CRC_LENGTH])
        if (resp_crc[0] != expected_crc[0]) or (resp_crc[1] !=
                                                expected_crc[1]):
            raise OSError('invalid response CRC')

        if (response[0] != slave_addr):
            raise ValueError('wrong slave address')

        if (response[1] == (function_code + Const.ERROR_BIAS)):
            raise ValueError('slave returned exception code: {:d}'.format(
                response[2]))

        hdr_length = (Const.RESPONSE_HDR_LENGTH +
                      1) if count else Const.RESPONSE_HDR_LENGTH

        return response[hdr_length:len(response) - Const.CRC_LENGTH]

    def read_coils(self, slave_addr, starting_addr, coil_qty):
        modbus_pdu = functions.read_coils(starting_addr, coil_qty)

        resp_data = self._send_receive(modbus_pdu, slave_addr, True)
        status_pdu = self._bytes_to_bool(resp_data)

        return status_pdu

    def read_discrete_inputs(self, slave_addr, starting_addr, input_qty):
        modbus_pdu = functions.read_discrete_inputs(starting_addr, input_qty)

        resp_data = self._send_receive(modbus_pdu, slave_addr, True)
        status_pdu = self._bytes_to_bool(resp_data)

        return status_pdu

    def read_holding_registers(self,
                               slave_addr,
                               starting_addr,
                               register_qty,
                               signed=True):
        modbus_pdu = functions.read_holding_registers(starting_addr,
                                                      register_qty)

        resp_data = self._send_receive(modbus_pdu, slave_addr, True)
        register_value = self._to_short(resp_data, signed)

        return register_value

    def read_input_registers(self,
                             slave_addr,
                             starting_address,
                             register_quantity,
                             signed=True):
        modbus_pdu = functions.read_input_registers(starting_address,
                                                    register_quantity)

        resp_data = self._send_receive(modbus_pdu, slave_addr, True)
        register_value = self._to_short(resp_data, signed)

        return register_value

    def write_single_coil(self, slave_addr, output_address, output_value):
        modbus_pdu = functions.write_single_coil(output_address, output_value)

        resp_data = self._send_receive(modbus_pdu, slave_addr, False)
        operation_status = functions.validate_resp_data(
            resp_data,
            Const.WRITE_SINGLE_COIL,
            output_address,
            value=output_value,
            signed=False)

        return operation_status

    def write_single_register(self,
                              slave_addr,
                              register_address,
                              register_value,
                              signed=True):
        modbus_pdu = functions.write_single_register(register_address,
                                                     register_value, signed)

        resp_data = self._send_receive(modbus_pdu, slave_addr, False)
        operation_status = functions.validate_resp_data(
            resp_data,
            Const.WRITE_SINGLE_REGISTER,
            register_address,
            value=register_value,
            signed=signed)

        return operation_status

    def write_multiple_coils(self, slave_addr, starting_address,
                             output_values):
        modbus_pdu = functions.write_multiple_coils(starting_address,
                                                    output_values)

        resp_data = self._send_receive(modbus_pdu, slave_addr, False)
        operation_status = functions.validate_resp_data(
            resp_data,
            Const.WRITE_MULTIPLE_COILS,
            starting_address,
            quantity=len(output_values))

        return operation_status

    def write_multiple_registers(self,
                                 slave_addr,
                                 starting_address,
                                 register_values,
                                 signed=True):
        modbus_pdu = functions.write_multiple_registers(
            starting_address, register_values, signed)

        resp_data = self._send_receive(modbus_pdu, slave_addr, False)
        operation_status = functions.validate_resp_data(
            resp_data,
            Const.WRITE_MULTIPLE_REGISTERS,
            starting_address,
            quantity=len(register_values))

        return operation_status

    def send_response(self,
                      slave_addr,
                      function_code,
                      request_register_addr,
                      request_register_qty,
                      request_data,
                      values=None,
                      signed=True):
        modbus_pdu = functions.response(function_code, request_register_addr,
                                        request_register_qty, request_data,
                                        values, signed)
        self._send(modbus_pdu, slave_addr)

    def send_exception_response(self, slave_addr, function_code,
                                exception_code):
        modbus_pdu = functions.exception_response(function_code,
                                                  exception_code)
        self._send(modbus_pdu, slave_addr)

    def get_request(self, unit_addr_list, timeout=None):
        req = self._uart_read_frame(timeout)

        if len(req) < 8:
            return None

        if req[0] not in unit_addr_list:
            return None

        req_crc = req[-Const.CRC_LENGTH:]
        req_no_crc = req[:-Const.CRC_LENGTH]
        expected_crc = self._calculate_crc16(req_no_crc)
        if (req_crc[0] != expected_crc[0]) or (req_crc[1] != expected_crc[1]):
            return None

        try:
            request = Request(self, req_no_crc)
        except ModbusException as e:
            self.send_exception_response(req[0], e.function_code,
                                         e.exception_code)
            return None

        return request
Example #4
0
class uModBusSerial:
    def __init__(self,
                 uart_id,
                 baudrate=9600,
                 data_bits=8,
                 stop_bits=1,
                 parity=None,
                 pins=None,
                 ctrl_pin=None):
        pinsLen = len(pins)
        if pins == None or pinsLen < 2 or pinsLen > 4 or pinsLen == 3:
            raise ValueError(
                'pins should contain pin names/numbers for: tx, rx, [rts, cts]'
            )
        tx = pins[0]
        rx = pins[1]
        if pinsLen == 4:
            rts = pins[2]
            cts = pins[3]
            self._uart = UART(uart_id, baudrate=baudrate, bits=data_bits, parity=parity, \
                          stop=stop_bits, timeout_char=10, tx=tx, rx=rx, rts=rts, cts=cts)
        else:
            self._uart = UART(uart_id, baudrate=baudrate, bits=data_bits, parity=parity, \
                            stop=stop_bits, timeout_char=10, tx=tx, rx=rx)
        #self._uart = UART(uart_id, baudrate=baudrate, bits=data_bits, parity=parity, \
        #                  stop=stop_bits, timeout_chars=10, pins=pins)
        if ctrl_pin is not None:
            self._ctrlPin = Pin(ctrl_pin, mode=Pin.OUT)
        else:
            self._ctrlPin = None
        self.char_time_ms = (1000 * (data_bits + stop_bits + 2)) // baudrate

    def _calculate_crc16(self, data):
        crc = 0xFFFF

        for char in data:
            crc = (crc >> 8) ^ Const.CRC16_TABLE[((crc) ^ char) & 0xFF]

        return struct.pack('<H', crc)

    def _bytes_to_bool(self, byte_list):
        bool_list = []
        for index, byte in enumerate(byte_list):
            bool_list.extend([bool(byte & (1 << n)) for n in range(8)])

        return bool_list

    def _to_short(self, byte_array, signed=True):
        response_quantity = int(len(byte_array) / 2)
        fmt = '>' + (('h' if signed else 'H') * response_quantity)

        return struct.unpack(fmt, byte_array)

    def _exit_read(self, response):
        if response[1] >= Const.ERROR_BIAS:
            if len(response) < Const.ERROR_RESP_LEN:
                return False
        elif (Const.READ_COILS <= response[1] <= Const.READ_INPUT_REGISTER):
            expected_len = Const.RESPONSE_HDR_LENGTH + 1 + response[
                2] + Const.CRC_LENGTH
            if len(response) < expected_len:
                return False
        elif len(response) < Const.FIXED_RESP_LEN:
            return False

        return True

    def _uart_read(self):
        response = bytearray()

        for x in range(1, 40):
            if self._uart.any():
                response.extend(self._uart.read())
                #response.extend(self._uart.readall())
                # variable length function codes may require multiple reads
                if self._exit_read(response):
                    break
            time.sleep(0.05)

        return response

    def _send_receive(self, modbus_pdu, slave_addr, count):
        serial_pdu = bytearray()
        serial_pdu.append(slave_addr)
        serial_pdu.extend(modbus_pdu)

        crc = self._calculate_crc16(serial_pdu)
        serial_pdu.extend(crc)

        # flush the Rx FIFO
        self._uart.read()
        if self._ctrlPin:
            self._ctrlPin(1)
        self._uart.write(serial_pdu)
        if self._ctrlPin:
            while not self._uart.wait_tx_done(2):
                machine.idle()
            time.sleep_ms(1 + self.char_time_ms)
            self._ctrlPin(0)

        return self._validate_resp_hdr(self._uart_read(), slave_addr,
                                       modbus_pdu[0], count)

    def _validate_resp_hdr(self, response, slave_addr, function_code, count):

        if len(response) == 0:
            raise OSError('no data received from slave')

        resp_crc = response[-Const.CRC_LENGTH:]
        expected_crc = self._calculate_crc16(response[0:len(response) -
                                                      Const.CRC_LENGTH])
        if (resp_crc[0] != expected_crc[0]) or (resp_crc[1] !=
                                                expected_crc[1]):
            raise OSError('invalid response CRC')

        if (response[0] != slave_addr):
            raise ValueError('wrong slave address')

        if (response[1] == (function_code + Const.ERROR_BIAS)):
            raise ValueError('slave returned exception code: {:d}'.format(
                response[2]))

        hdr_length = (Const.RESPONSE_HDR_LENGTH +
                      1) if count else Const.RESPONSE_HDR_LENGTH

        return response[hdr_length:len(response) - Const.CRC_LENGTH]

    def read_coils(self, slave_addr, starting_addr, coil_qty):
        modbus_pdu = functions.read_coils(starting_addr, coil_qty)

        resp_data = self._send_receive(modbus_pdu, slave_addr, True)
        status_pdu = self._bytes_to_bool(resp_data)

        return status_pdu

    def read_discrete_inputs(self, slave_addr, starting_addr, input_qty):
        modbus_pdu = functions.read_discrete_inputs(starting_addr, input_qty)

        resp_data = self._send_receive(modbus_pdu, slave_addr, True)
        status_pdu = self._bytes_to_bool(resp_data)

        return status_pdu

    def read_holding_registers(self,
                               slave_addr,
                               starting_addr,
                               register_qty,
                               signed=True):
        modbus_pdu = functions.read_holding_registers(starting_addr,
                                                      register_qty)

        resp_data = self._send_receive(modbus_pdu, slave_addr, True)
        register_value = self._to_short(resp_data, signed)

        return register_value

    def read_input_registers(self,
                             slave_addr,
                             starting_address,
                             register_quantity,
                             signed=True):
        modbus_pdu = functions.read_input_registers(starting_address,
                                                    register_quantity)

        resp_data = self._send_receive(modbus_pdu, slave_addr, True)
        register_value = self._to_short(resp_data, signed)

        return register_value

    def write_single_coil(self, slave_addr, output_address, output_value):
        modbus_pdu = functions.write_single_coil(output_address, output_value)

        resp_data = self._send_receive(modbus_pdu, slave_addr, False)
        operation_status = functions.validate_resp_data(
            resp_data,
            Const.WRITE_SINGLE_COIL,
            output_address,
            value=output_value,
            signed=False)

        return operation_status

    def write_single_register(self,
                              slave_addr,
                              register_address,
                              register_value,
                              signed=True):
        modbus_pdu = functions.write_single_register(register_address,
                                                     register_value, signed)

        resp_data = self._send_receive(modbus_pdu, slave_addr, False)
        operation_status = functions.validate_resp_data(
            resp_data,
            Const.WRITE_SINGLE_REGISTER,
            register_address,
            value=register_value,
            signed=signed)

        return operation_status

    def write_multiple_coils(self, slave_addr, starting_address,
                             output_values):
        modbus_pdu = functions.write_multiple_coils(starting_address,
                                                    output_values)

        resp_data = self._send_receive(modbus_pdu, slave_addr, False)
        operation_status = functions.validate_resp_data(
            resp_data,
            Const.WRITE_MULTIPLE_COILS,
            starting_address,
            quantity=len(output_values))

        return operation_status

    def write_multiple_registers(self,
                                 slave_addr,
                                 starting_address,
                                 register_values,
                                 signed=True):
        modbus_pdu = functions.write_multiple_registers(
            starting_address, register_values, signed)

        resp_data = self._send_receive(modbus_pdu, slave_addr, False)
        operation_status = functions.validate_resp_data(
            resp_data,
            Const.WRITE_MULTIPLE_REGISTERS,
            starting_address,
            quantity=len(register_values))

        return operation_status

    def close(self):
        if self._uart == None:
            return
        try:
            self._uart.deinit()
        except Exception:
            pass
Example #5
0
class Serial:
    def __init__(self,
                 uart_id,
                 baudrate=9600,
                 data_bits=8,
                 stop_bits=1,
                 parity=None,
                 pins=None,
                 ctrl_pin=None):
        self._uart = UART(uart_id,
                          baudrate=baudrate,
                          bits=data_bits,
                          parity=parity,
                          stop=stop_bits,
                          timeout_chars=7,
                          pins=pins)
        if ctrl_pin is not None:
            self._ctrlPin = Pin(ctrl_pin, mode=Pin.OUT)
        else:
            self._ctrlPin = None
        self.char_time_ms = (1000 * (data_bits + stop_bits + 2)) // baudrate
        self.reply_timeout_ms = 1000

    def _calculate_crc16(self, data):
        crc = 0xFFFF

        for char in data:
            crc = (crc >> 8) ^ Const.CRC16_TABLE[((crc) ^ char) & 0xFF]

        return struct.pack('<H', crc)

    def _bytes_to_bool(self, byte_list):
        bool_list = []
        for index, byte in enumerate(byte_list):
            bool_list.extend([bool(byte & (1 << n)) for n in range(8)])

        return bool_list

    def _to_short(self, byte_array, signed=True):
        response_quantity = int(len(byte_array) / 2)
        fmt = '>' + (('h' if signed else 'H') * response_quantity)

        return struct.unpack(fmt, byte_array)

    def _exit_read(self, response):
        if response[1] >= Const.ERROR_BIAS:
            if len(response) < Const.ERROR_RESP_LEN:
                return False
        elif (Const.READ_COILS <= response[1] <= Const.READ_INPUT_REGISTER):
            expected_len = Const.RESPONSE_HDR_LENGTH + 1 + response[
                2] + Const.CRC_LENGTH
            if len(response) < expected_len:
                return False
        elif len(response) < Const.FIXED_RESP_LEN:
            return False

        return True

    def _uart_read(self):
        response = bytearray()

        tickRead = time.ticks_ms()

        machine.idle()
        inBuffer = self._uart.any()

        while not inBuffer:
            if abs(time.ticks_diff(tickRead,
                                   time.ticks_ms())) > self.reply_timeout_ms:
                print('nothing')
                return response
            machine.idle()
            inBuffer = self._uart.any()

        tickRead = time.ticks_ms()
        while True:
            if inBuffer:
                chunk = self._uart.read(inBuffer)
                if len(response) + len(chunk) > 240:
                    raise OSError('RX Buffer Overflow')
                response.extend(chunk)
                tickRead = time.ticks_ms()
            elif abs(time.ticks_diff(
                    tickRead, time.ticks_ms())) >= self.char_time_ms * 4:
                break
            machine.idle()
            inBuffer = self._uart.any()

        return response

    def _send_receive(self, modbus_pdu, slave_addr, count):
        serial_pdu = bytearray()
        serial_pdu.append(slave_addr)
        serial_pdu.extend(modbus_pdu)

        crc = self._calculate_crc16(serial_pdu)
        serial_pdu.extend(crc)

        # flush the Rx FIFO
        self._uart.read()
        if self._ctrlPin:
            self._ctrlPin(1)
        self._uart.write(serial_pdu)
        if self._ctrlPin:
            while not self._uart.wait_tx_done(2):
                machine.idle()
            time.sleep_ms(1 + self.char_time_ms)
            self._ctrlPin(0)
            time.sleep_ms(1 + self.char_time_ms)
            self._uart.read()

        return self._validate_resp_hdr(self._uart_read(), slave_addr,
                                       modbus_pdu[0], count)

    def _validate_resp_hdr(self, response, slave_addr, function_code, count):

        if len(response) == 0:
            raise OSError('no data received from slave')

        resp_crc = response[-Const.CRC_LENGTH:]
        expected_crc = self._calculate_crc16(response[0:len(response) -
                                                      Const.CRC_LENGTH])
        if (resp_crc[0] != expected_crc[0]) or (resp_crc[1] !=
                                                expected_crc[1]):
            raise OSError('invalid response CRC')

        if (response[0] != slave_addr):
            raise ValueError('wrong slave address')

        if (response[1] == (function_code + Const.ERROR_BIAS)):
            raise ValueError('slave returned exception code: {:d}'.format(
                response[2]))

        hdr_length = (Const.RESPONSE_HDR_LENGTH +
                      1) if count else Const.RESPONSE_HDR_LENGTH

        return response[hdr_length:len(response) - Const.CRC_LENGTH]

    def read_coils(self, slave_addr, starting_addr, coil_qty):
        modbus_pdu = functions.read_coils(starting_addr, coil_qty)

        resp_data = self._send_receive(modbus_pdu, slave_addr, True)
        status_pdu = self._bytes_to_bool(resp_data)

        return status_pdu

    def read_discrete_inputs(self, slave_addr, starting_addr, input_qty):
        modbus_pdu = functions.read_discrete_inputs(starting_addr, input_qty)

        resp_data = self._send_receive(modbus_pdu, slave_addr, True)
        status_pdu = self._bytes_to_bool(resp_data)

        return status_pdu

    def read_holding_registers(self,
                               slave_addr,
                               starting_addr,
                               register_qty,
                               signed=True):
        modbus_pdu = functions.read_holding_registers(starting_addr,
                                                      register_qty)

        resp_data = self._send_receive(modbus_pdu, slave_addr, True)
        register_value = self._to_short(resp_data, signed)

        return register_value

    def read_input_registers(self,
                             slave_addr,
                             starting_address,
                             register_quantity,
                             signed=True):
        modbus_pdu = functions.read_input_registers(starting_address,
                                                    register_quantity)

        resp_data = self._send_receive(modbus_pdu, slave_addr, True)
        register_value = self._to_short(resp_data, signed)

        return register_value

    def write_single_coil(self, slave_addr, output_address, output_value):
        modbus_pdu = functions.write_single_coil(output_address, output_value)

        resp_data = self._send_receive(modbus_pdu, slave_addr, False)
        operation_status = functions.validate_resp_data(
            resp_data,
            Const.WRITE_SINGLE_COIL,
            output_address,
            value=output_value,
            signed=False)

        return operation_status

    def write_single_register(self,
                              slave_addr,
                              register_address,
                              register_value,
                              signed=True):
        modbus_pdu = functions.write_single_register(register_address,
                                                     register_value, signed)

        resp_data = self._send_receive(modbus_pdu, slave_addr, False)
        operation_status = functions.validate_resp_data(
            resp_data,
            Const.WRITE_SINGLE_REGISTER,
            register_address,
            value=register_value,
            signed=signed)

        return operation_status

    def write_multiple_coils(self, slave_addr, starting_address,
                             output_values):
        modbus_pdu = functions.write_multiple_coils(starting_address,
                                                    output_values)

        resp_data = self._send_receive(modbus_pdu, slave_addr, False)
        operation_status = functions.validate_resp_data(
            resp_data,
            Const.WRITE_MULTIPLE_COILS,
            starting_address,
            quantity=len(output_values))

        return operation_status

    def write_multiple_registers(self,
                                 slave_addr,
                                 starting_address,
                                 register_values,
                                 signed=True):
        modbus_pdu = functions.write_multiple_registers(
            starting_address, register_values, signed)

        resp_data = self._send_receive(modbus_pdu, slave_addr, False)
        operation_status = functions.validate_resp_data(
            resp_data,
            Const.WRITE_MULTIPLE_REGISTERS,
            starting_address,
            quantity=len(register_values))

        return operation_status