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')")