Python实现Modbus RTU读取LOVATO DME电表报Illegal Address故障求助
Modbus RTU读取LOVATO DME D301 MID电表报Illegal Address问题排查
先排除地址锁定可能
PC端LOVATO Xprss能正常连接读取电表数据,说明电表地址未被锁定,设备本身通信权限正常,问题出在代码配置或参数匹配上。
核心排查方向及解决方法
寄存器地址偏移问题
多数电表厂商的Modbus文档采用1-based寄存器地址标注,但pymodbus的read_holding_registers方法第一个参数要求是0-based索引(即文档地址减1)。你代码中用的地址58如果是文档里的1-based地址,实际应传入57。寄存器类型不匹配
确认有功功率对应的寄存器类型:部分设备的实时功率数据存储在**输入寄存器(Input Registers)**而非保持寄存器(Holding Registers)。如果PC软件读取的是输入寄存器,代码中应替换为read_input_registers方法。从站地址与通信参数校验
- 核对LOVATO电表的从站地址:PC软件连接时使用的从站地址是否为1?若不是,需修改代码中
read_holding_registers的第三个参数(slave地址)。 - 确认电表通信参数:波特率、奇偶校验、停止位需与代码完全一致(PC软件连接LOVATO时的参数要和代码里的9600/N/8/1匹配)。
- 核对LOVATO电表的从站地址:PC软件连接时使用的从站地址是否为1?若不是,需修改代码中
修正后的测试代码示例
from pymodbus.client import ModbusSerialClient as ModbusClient # 初始化客户端并显式连接 client = ModbusClient(method='rtu', port='/dev/ttyUSB0', timeout=1, stopbits=1, bytesize=8, parity='N', baudrate=9600) client.connect() # 测试LOVATO电表(假设文档地址58是1-based,转0-based为57) try: # 先尝试保持寄存器,若失败换read_input_registers w1_response = client.read_holding_registers(57, 1, slave=1) if not w1_response.isError(): w1_val = w1_response.registers[0] / 10 print(f"LOVATO DME 有功功率: {w1_val}") else: print(f"LOVATO 保持寄存器读取错误: {w1_response}") # 尝试输入寄存器 w1_input_response = client.read_input_registers(57, 1, slave=1) if not w1_input_response.isError(): w1_input_val = w1_input_response.registers[0] / 10 print(f"LOVATO DME 有功功率(输入寄存器): {w1_input_val}") else: print(f"LOVATO 输入寄存器读取错误: {w1_input_response}") except Exception as e: print(f"LOVATO 读取异常: {e}") # EM24电表读取(保持原有逻辑) w2_response = client.read_holding_registers(40, 1, slave=2) if not w2_response.isError(): w2_val = w2_response.registers[0] / 10 print(f"CARLO GAVAZZI EM24 有功功率: {w2_val}") else: print(f"EM24 读取错误: {w2_response}") # 关闭连接 client.close()
总结
问题大概率是寄存器地址的0/1基偏移错误或寄存器类型选错,硬件及电表本身无锁定问题,按上述步骤调整即可解决。
内容的提问来源于stack exchange,提问作者Maario
相关产品推荐
相关产品推荐

