This is little bit tricky because all Modbus registers are only 16-bit unsigned data
(those who are intended for sending numbers
):
Object type | Access | Size | Address Space
Coil | Read-write | 1 bit | 00001 - 09999
Discrete input | Read-only | 1 bit | 10001 - 19999
Input register | Read-only | 16 bits | 30001 - 39999
Holding register | Read-write | 16 bits | 40001 - 49999
- There for all the data you send needs to be unsigned 16-bit (in our case
Int
).
- You have to handle the data transformation from
Float
to Int
and from Int
to Float
both on Server side and Client side.
- The code below is for Python program to be ran as
Client
.
- In order to send
Float
data via Modbus you need to transform them via simple multiplication or division.
This is code that will allow you as a Client
send positive Float
numbers from Python to Modbus server:
from pyModbusTCP.client import ModbusClient
def send_single_float(client, reg_addr, reg_value, setting, by):
if setting == "multiply":
client.write_single_register(reg_addr = reg_addr, reg_value = int(reg_value*by))
elif setting == "divide":
if reg_value == 0:
client.write_single_register(reg_addr = reg_addr, reg_value = int(reg_value))
else:
client.write_single_register(reg_addr = reg_addr, reg_value = int(reg_value/by))
else:
raise TypeError("Only string with following values can be set for 'Setting' attribute: ('multiply', 'divide')")
c = ModbusClient("localhost")
c.open()
my_float = 10.05
while True:
send_single_float(c, 0, my_float, "multiply", 100)
You can use also this function to read Float
numbers from Modbus:
def read_single_float(client, reg_addr, setting, by):
if setting == "multiply":
return client.read_holding_registers(reg_addr = reg_addr, reg_nb = 1)[0] * by
elif setting == "divide":
data = client.read_holding_registers(reg_addr = reg_addr, reg_nb = 1)[0]
if data == 0:
return data
else:
return data / by
else:
raise TypeError("Only string with following values can be set for 'Setting' attribute: ('multiply', 'divide')")