Python Modbus字符串解码问题
我对带字符串的pymodbus解码器有问题。例如,当我试图阅读'abcdefg'时,pymodbus会给我'badcfehg'。字节顺序和字顺序不会改变结果 这是我的密码:Python Modbus字符串解码问题,python,modbus,pymodbus,Python,Modbus,Pymodbus,我对带字符串的pymodbus解码器有问题。例如,当我试图阅读'abcdefg'时,pymodbus会给我'badcfehg'。字节顺序和字顺序不会改变结果 这是我的密码: result=client.read_holding_registers(25000,4) decoder = BinaryPayloadDecoder.fromRegisters(result.registers,byteorder=Endian.Little,wordorder=Endian.Big) decoder.d
result=client.read_holding_registers(25000,4)
decoder = BinaryPayloadDecoder.fromRegisters(result.registers,byteorder=Endian.Little,wordorder=Endian.Big)
decoder.decode_string(8)
有人能解释为什么订单不会改变结果吗?我尝试与建设者,这是同样的问题。但是,我没有这个问题,例如32位浮点
我还尝试了pymodbus的旧版本,它可以工作:
decoder = BinaryPayloadDecoder.fromRegisters(registers,endian=Endian.Little)
注意:我已经阅读了以下主题:但我没有任何访问modbus服务器的权限。问题是modbus规范没有定义字符字符串的两个字节的发送顺序,甚至没有定义32位类型的16位字的发送顺序 然后,一些Modbus设备按顺序发送字节或字,而其他设备则相反 如果您正在编写Modbus客户端,则应在配置中添加选项,以便能够反转32位数据类型中字节和16位字的顺序
我在字节顺序不工作时遇到了同样的问题(wordorder似乎没问题)。我提出的解决方案是使用Struct:
import struct
然后:
count=4#读取4个16位寄存器
结果=客户端。读取\保存\寄存器(25000,计数)
对于范围内的i(计数):
result.registers[i]=struct.unpack(“H”,result.registers[i]))[0]
解码器=二进制PayloadDecoder.fromRegisters(result.registers)
打印(decoder.decode_string(7))35;,因为字符串长度为7个字符
这使用Struct解包并打包为无符号短整数。endianness并不重要,因为您所做的只是交换字节。结果将覆盖寄存器,这样您就可以像平常一样使用BinaryPayloadDecoder
我更愿意遍历响应,而不是使用range(count),但是找不到一种方法来完成,我想发布这个解决方法。如果我弄明白了,我会告诉你的。你好,本莫,从外观上看,你可能发现了一个bug。我认为您有三个选择:亲自查看代码以查看从旧版本到新版本的更改,报告问题或坚持使用旧版本。如果您决定亲自查看代码,如果您需要帮助,我愿意在这里为您提供帮助。该问题现已确定,将在Pymodbus的未来版本中解决:谢谢您的回答。是的,这就是“文字顺序”和“字节顺序”的目的,不是吗?当我在pymodbus的旧版本中更改单词顺序时,它可以工作(endian=endian.Big=>endian=endian.Little)。但是,它不适用于pymodbus的新版本。我遗漏了什么吗?原因可能是新版本的开发人员决定用Endian.Little替换Endian.Big。我在回答中试图说的是,如果数据(无论是字符串还是32位)读取不正确,您应该给软件用户交换尾数的机会。Modbus驱动程序通常就是这样做的,因为这个问题经常发生。
count = 4 #Read 4 16bit registers
result = client.read_holding_registers(25000,count)
for i in range(count):
result.registers[i] = struct.unpack("<H", struct.pack(">H", result.registers[i]))[0]
decoder = BinaryPayloadDecoder.fromRegisters(result.registers)
print(decoder.decode_string(7)) #Since string is 7 characters long