读写浮点型在Modbus Python中



很抱歉我的英语不好。我尝试使用pyModbusTCP lib通过Modbus在python中的plc寄存器中写入和读取float。这是我的代码,不幸的是没有去。。。

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=ip, port=porta, auto_open=True)
# write 10.0 at @0
c.write_float(registrow, [var]) 
print("write ok")
# read @0 to 9
float_l = c.read_float(registror)
print(float_l)
c.close()

有人能帮我吗?

这有点棘手,因为所有Modbus寄存器都只有16-bit unsigned data(用于发送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
  • 您发送的所有数据都需要是无符号的16位(在我们的情况下是Int(
  • 您必须在服务器端和客户端处理从FloatInt以及从IntFloat的数据转换
  • 下面的代码用于将Python程序作为Client运行
  • 为了通过Modbus发送Float数据,您需要通过简单的乘法或除法对其进行转换

这是一个允许您作为Client从Python向Modbus服务器发送正Float数字的代码:

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)

您也可以使用此功能从Modbus:读取Float数字

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

最新更新