Pymodbus 读取和解码寄存器值
Pymodbus read and decode register value
我是 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 寄存器文档中提取和读取数据?
非常感谢
据我所知,您正在尝试连接到 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.payload
中的 BinaryPayloadDecoder
(有关详细信息,请参阅 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()
当你打印它时,它应该会给你一些有意义的功率值。
我是 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 寄存器文档中提取和读取数据?
非常感谢
据我所知,您正在尝试连接到 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.payload
中的 BinaryPayloadDecoder
(有关详细信息,请参阅 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()
当你打印它时,它应该会给你一些有意义的功率值。