Python 3.8环境下RTU send_message间歇性失败问题求助
解决Windows下umodbus RTU随机出现ClearCommError (错误码995)问题
问题根源
错误码995(The I/O operation has been aborted because of either a thread exit or an application request.)本质是Windows系统中止了串口I/O操作,常见触发场景包括:
- 长期持有的串口连接被系统资源回收
- pyserial/umodbus旧版本的兼容性bug
- USB串口设备的电源管理策略干扰
- 串口操作超时或状态异常未被正确处理
解决方案
1. 优化串口连接生命周期管理
避免长期持有同一个串口对象,建议每次发送前重新初始化串口,发送完成后立即关闭,减少资源占用:
import serial from umodbus.client.serial import rtu import time def init_serial(): return serial.Serial( port="COM3", # 替换为你的实际串口号 baudrate=115200, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, timeout=10, write_timeout=5 ) while True: ser = None try: ser = init_serial() rtu.send_message(msg, ser) except Exception as e: print(f"发送失败: {str(e)}") finally: if ser and ser.is_open: ser.close() time.sleep(120)
2. 升级依赖库版本
当前使用的umodbus 1.0.4和配套的pyserial可能存在Windows串口处理的bug,升级到最新稳定版:
pip install --upgrade pyserial umodbus
3. 禁用USB串口设备的电源管理
Windows可能自动关闭USB串口设备以省电,导致连接中断:
- 打开设备管理器,找到你的串口设备(通常在「端口(COM和LPT)」下)
- 右键选择「属性」→「电源管理」
- 取消勾选「允许计算机关闭此设备以节约电源」,点击确定
4. 异常捕获与自动恢复
针对特定错误做捕获,出现异常时自动重置串口连接,避免程序崩溃:
from umodbus.client.serial import rtu import serial import time # 初始化串口 serial_port = serial.Serial( port="COM3", baudrate=115200, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, timeout=10, write_timeout=5 ) while True: try: rtu.send_message(msg, serial_port) except serial.SerialException as e: if "ClearCommError failed" in str(e) or "995" in str(e): print("检测到串口异常,正在重置连接...") if serial_port.is_open: serial_port.close() serial_port.open() else: raise # 其他异常正常抛出 time.sleep(120)
5. 调整串口flush策略
原错误触发于serial_port.flush(),可以尝试手动控制flush时机,或者在umodbus的send_message调用前先检查串口状态:
# 在发送前确保串口状态正常 if not serial_port.is_open: serial_port.open() # 手动flush并捕获异常 try: serial_port.flushOutput() except serial.SerialException: serial_port.close() serial_port.open() rtu.send_message(msg, serial_port)
内容的提问来源于stack exchange,提问作者주석윤
相关产品推荐
相关产品推荐

