使用pymodbus v3.0.2读取Modbus RTU设备频繁报错:ModbusIOException无registers属性
解决Modbus RTU读取输入寄存器时的ModbusIOException问题
问题分析
你遇到的'ModbusIOException' object has no attribute 'registers'错误,本质是读取失败时read_input_registers返回的是异常对象而非正常响应,直接访问.registers就会触发属性错误。偶尔成功说明串口参数和设备基本匹配,但存在连接稳定性或响应超时的问题。
解决方案
1. 先校验响应再访问寄存器
修改读取函数,先判断响应是否正常,避免直接访问异常对象的属性:
def read_mbr(): response = client.read_input_registers(0, 15, unit=1) # 检查响应是否正常 if not response.isError(): return response.registers else: print(f"读取失败: {response}") return None
2. 完善客户端初始化参数
添加超时设置,避免因设备响应慢导致读取失败;同时再次确认设备的串口参数(波特率、停止位等)和代码完全一致:
client = ModbusSerialClient( method="rtu", port="/dev/ttyUSB0", stopbits=2, bytesize=8, parity="N", baudrate=9600, timeout=3 # 添加超时,单位秒 )
3. 增加连接状态检查
在每次读取前检查串口连接是否正常,断开时自动重连:
def read_mbr(): # 检查连接状态,断开则重连 if not client.is_socket_open(): print("重新连接Modbus设备...") client.connect() response = client.read_input_registers(0, 15, unit=1) if not response.isError(): return response.registers else: print(f"读取错误: {response}") return None
4. 优化主循环逻辑
在主循环中处理read_mbr返回的None值,避免无效打印:
while True: try: data = read_mbr() if data: print(data) except Exception as e: print(f"异常: {e}") time.sleep(1) time.sleep(2) # 适当延长读取间隔,给设备足够响应时间
5. 硬件与驱动排查
- 检查USB转串口线的兼容性,尽量使用工业级线缆,避免信号干扰;
- 确认Ubuntu系统中USB转串口的驱动是否正常(可通过
dmesg | grep ttyUSB查看设备识别情况)。
修改后的完整代码
#!/usr/bin/python3 import time import datetime from datetime import timedelta import mysql.connector from mysql.connector import Error from pymodbus.client import ModbusSerialClient client = ModbusSerialClient( method="rtu", port="/dev/ttyUSB0", stopbits=2, bytesize=8, parity="N", baudrate=9600, timeout=3 ) connection = client.connect() if connection is True: print("Modbus Connection Successful") def read_mbr(): if not client.is_socket_open(): print("重新连接Modbus设备...") client.connect() response = client.read_input_registers(0, 15, unit=1) if not response.isError(): return response.registers else: print(f"读取错误: {response}") return None while True: try: data = read_mbr() if data: print(data) except Exception as e: print(f"异常: {e}") time.sleep(1) time.sleep(2)
内容的提问来源于stack exchange,提问作者Md. Mozammel Hossain
相关产品推荐
相关产品推荐

