You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

读取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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 22:30:51