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

使用Python通过IP读取Modbus控制器数据遇AttributeError求助

问题:读取Modbus控制器数据时触发AttributeError错误

尝试通过IP地址从Modbus控制器读取数据,使用的Python代码如下:

from pymodbus.client.sync import ModbusTcpClient as ModbusClient

client = ModbusClient("10.98.237.80", port=502, auto_open=True)
client.connect()

rr = client.read_holding_registers(60, 2, unit=1)

print (rr.registers)

运行后出现如下异常:

2023-04-03 14:57:18,678 MainThread      DEBUG    sync           :216      Connection to Modbus server established. Socket ('10.80.144.99', 64492)
2023-04-03 14:57:18,680 MainThread      DEBUG    transaction    :140      Current transaction state - IDLE
2023-04-03 14:57:18,681 MainThread      DEBUG    transaction    :145      Running transaction 1
2023-04-03 14:57:18,682 MainThread      DEBUG    transaction    :273      SEND: 0x0 0x1 0x0 0x0 0x0 0x6 0x1 0x3 0x0 0x3c 0x0 0x2
2023-04-03 14:57:18,683 MainThread      DEBUG    sync           :76       New Transaction state 'SENDING'
2023-04-03 14:57:18,684 MainThread      DEBUG    transaction    :287      Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
2023-04-03 14:57:20,082 MainThread      DEBUG    transaction    :375      Changing transaction state from 'WAITING FOR REPLY' to 'PROCESSING REPLY'
2023-04-03 14:57:20,083 MainThread      DEBUG    transaction    :297      RECV: 0x0 0x1 0x0 0x0 0x0 0x3 0x1 0x83 0xfc
2023-04-03 14:57:20,084 MainThread      DEBUG    socket_framer  :147      Processing: 0x0 0x1 0x0 0x0 0x0 0x3 0x1 0x83 0xfc
2023-04-03 14:57:20,084 MainThread      DEBUG    factory        :266      Factory Response[131]
2023-04-03 14:57:20,085 MainThread      DEBUG    transaction    :454      Adding transaction 1
2023-04-03 14:57:20,085 MainThread      DEBUG    transaction    :465      Getting transaction 1
2023-04-03 14:57:20,086 MainThread      DEBUG    transaction    :224      Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-11-1ea661f8edc1> in <module>
      6 rr = client.read_holding_registers(60, 2, unit=1)
      7 
----> 8 print (rr.registers)

AttributeError: 'ExceptionResponse' object has no attribute 'registers'

解决方案

1. 错误原因解析

报错'ExceptionResponse' object has no attribute 'registers'说明Modbus控制器返回了错误响应,而非正常的寄存器数据。从日志里的响应数据0x1 0x83 0xfc可以看出:

  • 0x83是错误版的读保持寄存器功能码(正常功能码为0x03,错误响应会在功能码上加0x80);
  • 0xfc是控制器返回的错误码,这个不属于标准Modbus错误码,需要参考设备说明书确认含义。

2. 代码优化:先判断响应类型

修改代码,先检查响应是否为异常,避免直接访问registers报错,同时打印错误信息方便排查:

from pymodbus.client.sync import ModbusTcpClient as ModbusClient

client = ModbusClient("10.98.237.80", port=502, auto_open=True)
client.connect()

rr = client.read_holding_registers(60, 2, unit=1)

# 先判断是否为正常响应
if hasattr(rr, 'registers'):
    print("读取到的寄存器数据:", rr.registers)
else:
    print(f"Modbus错误码: {hex(rr.exception_code)}")
    # 标准Modbus错误码对应说明,供参考
    error_map = {
        0x01: "非法功能码:控制器不支持读保持寄存器操作",
        0x02: "非法数据地址:起始地址60超出控制器的保持寄存器范围",
        0x03: "非法数据值:读取的寄存器数量2不符合设备要求",
        0x04: "从站故障:控制器内部出现错误",
        0x05: "确认失败:设备无法执行请求",
        0x06: "从站忙:设备正在处理其他请求"
    }
    print(error_map.get(rr.exception_code, "未知错误码,请参考设备说明书"))

3. 关键排查点

  • 从站地址(unit参数):确认控制器的Modbus从站地址是否为1,部分设备默认地址为0或其他值;
  • 寄存器地址:注意Modbus有两种地址表示方式:基于0的索引和基于1的编号。pymodbus的read_holding_registers第一个参数是基于0的索引,如果设备文档里的地址是基于1的,需要减1后再传入;
  • 寄存器类型:如果要读取的是输入寄存器(而非保持寄存器),需要改用read_input_registers方法(对应功能码0x04);
  • 网络与服务状态:确认客户端与控制器在同一网段/路由可达,防火墙未阻挡502端口,且控制器的Modbus TCP服务已开启并监听502端口;
  • 设备说明书:针对返回的0xfc错误码,查看控制器的官方文档,确认具体错误原因。

内容的提问来源于stack exchange,提问作者SM079

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 22:07:49