【问题标题】:Read & Write Float in Modbus Python在 Modbus Python 中读取和写入浮点数
【发布时间】:2021-04-06 03:47:25
【问题描述】:

对不起,我的英语不好。 我尝试使用 pyModbusTCP lib 通过 Modbus 在 python 的 plc 寄存器中写入和读取浮点数。 这是我的代码,不幸的是没有去......

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()

有人可以帮我吗?

【问题讨论】:

  • 你能用更多信息更新这个问题吗?什么不起作用。该功能无法正确读取/写入。有错误,还有别的吗?
  • 从 write_float 方法中,我希望在我给它的寄存器中写入一个浮点数(var),它不会给我错误,但它不会写任何东西。从 read_float 我希望从特定寄存器中读取浮点数,但结果我总是“无”

标签: python modbus plc pymodbustcp


【解决方案1】:

这有点棘手,因为所有 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 将正数 Float 从 Python 发送到 Modbus 服务器:

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

【讨论】:

  • 如果答案帮助您留下+1green arrow,请! :)
猜你喜欢
  • 2014-10-13
  • 1970-01-01
  • 2019-10-08
  • 1970-01-01
  • 2021-06-13
  • 2019-01-20
  • 2011-07-20
  • 1970-01-01
  • 2017-11-26
相关资源
最近更新 更多