# Techman read / write values using Modbus

**URL:** <https://www.robotexchange.io/t/techman-read-write-values-using-modbus/866>\
**Category:** Public forum\
**Created:** [October 1, 2019, 9:33am UTC](https://www.robotexchange.io/t/techman-read-write-values-using-modbus/866 "2019-10-01T09:33:03Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mathijs](https://www.robotexchange.io/user_avatar/www.robotexchange.io/mathijs/32/7_2.png) [@Mathijs](https://www.robotexchange.io/u/Mathijs)\
**Post date:** [October 1, 2019, 9:33am UTC](https://www.robotexchange.io/t/techman-read-write-values-using-modbus/866/1 "2019-10-01T09:33:04Z")

</div>

You can read and write Modbus values with Python.

All you need is this Python module:  
[https://pypi.org/project/pymodbus/](https://pypi.org/project/pymodbus/)

```auto
from pyModbusTCP.client import ModbusClient
c = ModbusClient(host="192.168.0.1", auto_open=True)

while True:
    # read 16 bits at address 0, these are the Digital Outputs for the TechMan
    bits = c.read_coils(0, 16)
    print("bit ad #0 to 9: "+str(bits) if bits else "read error")
    # sleep 2s
    time.sleep(2)

```

It is also possible to read / write floats, but so far only user defined values can be read:

```auto
# how-to add float support to ModbusClient

from pyModbusTCP.client import ModbusClient
from pyModbusTCP import utils

class FloatModbusClient(ModbusClient):
    def read_float(self, address, number=1):
        reg_l = self.read_holding_registers(address, number * 2)
        if reg_l:
            return [utils.decode_ieee(f) for f in utils.word_list_to_long(reg_l)]
        else:
            return None

    def write_float(self, address, floats_list):
        b32_l = [utils.encode_ieee(f) for f in floats_list]
        b16_l = utils.long_list_to_word(b32_l)
        return self.write_multiple_registers(address, b16_l)

c = FloatModbusClient(host='192.168.0.1', port=502, auto_open=True)

c.write_float(9000, [123.0])
# read @0 to 9
float_l = c.read_float(9000)
print(float_l)

c.close()

```

---

<div class="post-metadata">

**Author:** ![13051091](https://www.robotexchange.io/letter_avatar_proxy/v4/letter/1/43a26b/32.png) [@13051091](https://www.robotexchange.io/u/13051091)\
**Post date:** [October 2, 2019, 9:55am UTC](https://www.robotexchange.io/t/techman-read-write-values-using-modbus/866/2 "2019-10-02T09:55:54Z")

</div>

To read a X,Y,Z coordinate you have to read a input register instead of a holding register. It still is a float so we copied the read\_float function and made some adjustments.

---

<div class="post-metadata">

**Author:** ![Mathijs](https://www.robotexchange.io/user_avatar/www.robotexchange.io/mathijs/32/7_2.png) [@Mathijs](https://www.robotexchange.io/u/Mathijs)\
**Post date:** [October 2, 2019, 11:11am UTC](https://www.robotexchange.io/t/techman-read-write-values-using-modbus/866/3 "2019-10-02T11:11:33Z")

</div>

Could you post your adjustments? 🙂

---

<div class="post-metadata">

**Author:** ![13051091](https://www.robotexchange.io/letter_avatar_proxy/v4/letter/1/43a26b/32.png) [@13051091](https://www.robotexchange.io/u/13051091)\
**Post date:** [October 2, 2019, 1:53pm UTC](https://www.robotexchange.io/t/techman-read-write-values-using-modbus/866/4 "2019-10-02T13:53:45Z")

</div>

We added this function to the class FloatModbusClient:

```
   class FloatModbusClient(ModbusClient):
        def read_float(self, address, number=1):
            reg_l = self.read_holding_registers(address, number * 2)
            if reg_l:
                return [utils.decode_ieee(f) for f in utils.word_list_to_long(reg_l)]
            else:
                return None
        
    def read_input_registers_float(self, address, number=1):
        reg_1 = self.read_input_registers(address, number * 2)
        if reg_1:
            return [utils.decode_ieee(f) for f in utils.word_list_to_long(reg_1)]
        else:
            return None

    def write_float(self, address, floats_list):
        b32_l = [utils.encode_ieee(f) for f in floats_list]
        b16_l = utils.long_list_to_word(b32_l)
        return self.write_multiple_registers(address, b16_l)
    
    def write_single_register_float(self, address, floats_list):
        b32_l = [utils.encode_ieee(f) for f in floats_list]
        b16_l = utils.long_list_to_word(b32_l)
        return self.write_single_register(address, b16_l)

```

And call the function in this way:

```
c_f = FloatModbusClient(host='192.168.0.1', port=502, auto_open=True)
x_pos = c_f.read_input_registers_float(7001,2)
print (x_pos)
```
