读取Modbus保持寄存器Float32数据异常,与ModScan32结果不符求解决
问题解决步骤
1. 修正寄存器地址错误
你代码里的address = 43026完全错误,Modbus保持寄存器的地址规则是:
- ModScan显示的是1基编号(比如3026)
- pymodbus库的
read_holding_registers用的是0基地址,所以需要把1基编号减1,也就是3026 - 1 = 3025。
2. 匹配ModScan的MSRF编码格式
ModScan的float(MSRF)模式对应IEEE754 32位浮点数的编码规则是:
- 字序(寄存器顺序):低地址寄存器存浮点数的低16位(Little Endian)
- 字节序(寄存器内部字节顺序):每个寄存器的字节是大端排序(Big Endian)
你的原代码字节序和字序设置错误,导致解析出完全不对的极小值。
修正后的代码
from pymodbus.client import ModbusSerialClient from pymodbus.payload import BinaryPayloadDecoder from pymodbus.constants import Endian import time # 初始化客户端,注意参数名是bytesize而不是bytes(规范写法) client = ModbusSerialClient(method='rtu', port='COM4', timeout=1, stopbits=1, bytesize=8, parity='E', baudrate=9600) connect_status = client.connect() print(f"连接状态: {connect_status}") while True: # 读取0基地址3025,对应1基的3026-3027两个寄存器 read_result = client.read_holding_registers(address=3025, count=2, unit=1) if not read_result.isError(): # 按MSRF模式解码:字节序Big,字序Little decoder = BinaryPayloadDecoder.fromRegisters( read_result.registers, byteorder=Endian.Big, wordorder=Endian.Little ) float_value = decoder.decode_32bit_float() print(f"解析结果: {round(float_value, 4)}") # 保留4位小数和ModScan一致 else: print(f"读取失败: {read_result}") time.sleep(1) # 测试时用1秒间隔,后续可改回100秒
额外注意事项
- 确认pymodbus版本:如果你的库是旧版本,
ModbusClient可能需要替换为ModbusSerialClient - 错误处理:增加
isError()判断可以避免读取失败时程序崩溃 - sleep时间:原代码的100秒间隔太长,测试阶段建议缩短为1秒,确认结果正确后再改回
内容的提问来源于stack exchange,提问作者Josephus Rizada
相关产品推荐
相关产品推荐

