Pymodbus 读取和解码寄存器值

Posted

技术标签:

【中文标题】Pymodbus 读取和解码寄存器值【英文标题】:Pymodbus read and decode register value 【发布时间】:2021-12-21 03:54:55 【问题描述】:

我是 modbus 通信的新手,我必须使用 modbus 协议从一个寄存器中从逆变器读取单个值(为此,我使用 python 和 pymodbus): 从逆变器文档中我读到了寄存器文档:

注册 ADR:31249 说明:PCC处系统的有功功率(W) 碳纳米管:2 类型:S32 格式:FIX0 访问:RO

好吧,我试试我的 python 脚本是这样的:

from pymodbus.client.sync import ModbusTcpClient
client = ModbusTcpClient("192.168.1.10", port=502, timeout=3)
client.connect()
read=client.read_holding_registers(address = 31249 ,count =2,unit=1)
read.registers

所以我有这个值:

[65535, 65535]

我猜这不是寄存器的解码值,所以我尝试解码提取值:

read_encoded = read.encode()
read_encoded
b'\xff\xff\xff\xff'
read_encoded_value = int.from_bytes(read_encoded, byteorder="big")
read_encoded_value

所以如果我打印我的变量,我会得到:

4294967295

这意味着价值有点大。 读取和解码我的 modbus 寄存器值的过程是否正确?

如何从我的逆变器的 modbus 寄存器文档中提取和读取数据?

提前非常感谢

【问题讨论】:

S32 通常表示“带符号的 32 位”,所以我怀疑您需要 int.from_bytes(b'\xff\xff\xff\xff', byteorder='big', signed=True)(结果为 -1)。如果没有关于控制器的信息,您正在投票,很难进一步评论。 【参考方案1】:

据我所知,您正在尝试连接到 SMA 逆变器。

阅读第一个manual 我发现它并不完全清楚,但您尝试读取的寄存器似乎不是保持寄存器而是输入寄存器(对于大多数 Modbus 设备,如果寄存器编号在 3XXXX 范围内通常表示输入寄存器,4XXXX是保持寄存器)。

第二个技巧是偏移量:pyModbus 不考虑协议中寄存器的寻址方式,因此您必须注意:

-当您尝试读取或写入输入寄存器时,您需要减去 30001。对于您的情况,即:31249-30001=1248(请注意,在一些奇怪的设备中,偏移量实际上是 30000,因此您可能想尝试一下也)。

-对于保存寄存器,偏移量显然是 40001。

如果我上面提到的手册对您的设备是正确的,那么您应该像现在一样寻址单元 2 而不是 1。如果这是正确的,您必须更改此行:

read=client.read_holding_registers(address = 31249 ,count=2,unit=1)

到:

read=client.read_holding_registers(address = 1248 ,count=2,unit=2)

一旦找到正确的寄存器,您就必须使用来自pymodbus.payloadBinaryPayloadDecoder(有关详细信息,请参阅this example)。

您可能需要执行以下操作(不要忘记上面的导入):

decoder = BinaryPayloadDecoder.fromRegisters(read.registers, byteorder=Endian.Big, wordorder=Endian.Big)

根据我的手册,单词 s 的格式是 Motorola big-endian,我猜字节也很大(不过,您可能必须尝试查看,直到找到正确的组合)。

最后,在构建解码器之后,您需要解码 32 位有符号整数,如下所示:

active_power_w = decoder.decode_32bit_int()

当你打印它时,它应该会给你一些有意义的力量价值。

【讨论】:

以上是关于Pymodbus 读取和解码寄存器值的主要内容,如果未能解决你的问题,请参考以下文章

Pymodbus:如何读取该输入寄存器的各个位?

将值分配给 TCP 服务器寄存器的 pymodbus 语法是啥?

如何让 pymodbus 与 PLC 正确通信?

Pymodbus/Twisted 异步客户端重新连接

具有多个从设备上下文的 pymodbus Modbus 服务器实现 - 写入寄存器会覆盖所有从设备

控制硬件在完成指令解码之前如何知道要读取哪些寄存器?