Python中ModbusTCP读取负数显示为大数的问题求助
解决Modbus TCP读取负数显示为大数的问题
你的问题本质是Modbus保持寄存器返回的是无符号16位整数,但实际存储的是有符号数的补码,导致负数被解析成了大的无符号值。
问题分析
你拿到的59142对应的二进制是1110011100000110,这是16位有符号数的补码(最高位为1,表示负数)。直接按无符号整数解析就会得到59142,而正确的有符号值应该是它对应的负数。
两种解决方法
方法1:手动计算补码转原码
16位有符号数的范围是-32768到32767,如果读取的值大于32767,就用值 - 65536(2^16)得到对应的负数:
def u16_to_s16(value): return value - 65536 if value > 32767 else value # 修改你的读取代码 self.export = u16_to_s16(self.c.read_holding_registers(37113, 2)[1])
测试你的值:59142 - 65536 = -6394,这就是正确的负数结果。
方法2:用struct模块自动转换
利用Python的struct模块,先把无符号整数打包成字节,再按有符号16位解析(注意Modbus通常用大端字节序>):
import struct raw_value = self.c.read_holding_registers(37113, 2)[1] # 打包成无符号大端16位,再解析成有符号大端16位 self.export = struct.unpack('>h', struct.pack('>H', raw_value))[0]
验证结果
修改后再打印,self.export就会显示为-6394.000000,二进制输出也会正确显示负数形式。
内容的提问来源于stack exchange,提问作者Mads Gadeberg
相关产品推荐
相关产品推荐

