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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 11:25:18