我有一个 USB 设备,有时会通过 USB 端口发送串行数据。问题是设备出现故障,有时会无缘无故地断开连接并再次连接到电脑。问题不大,但在这些情况下我需要重新初始化
serial.Serial(port)
实例,这有点烦人。该设备没有可以从我那里收到的任何命令,我可以验证它是否已连接。我可以编写一些东西来启动一个线程,定期监视设备或类似的东西,但这有点乏味,因为该设备与 Windows 和 Linux PC 一起使用,我需要考虑任何边缘情况和等等,这是相当烦人和乏味的工作。
是否有任何解决方案已经存在,我可以在其中附加一个回调来处理断开/连接事件或类似的解决方法?我正在寻找适用于 Windows 和 Linux 的解决方案(至少适用于 Windows)。购买新设备并不是解决方案。
遗憾的是,对于你的问题,没有现成的跨平台解决方案可以提供连接/断开连接回调。Windows 和 Linux 以不同的方式处理 USB 设备事件,并且没有统一的方法可以像你希望的那样直接获取通知。
不过,你可以使用多线程方法构建一个强大的解决方案。它可能没有看起来那么“乏味”。以下是如何做:
import serial
import time
from threading import Thread, Event
class UsbMonitor:
def __init__(self, port, baudrate, reconnect_interval=5):
self.port = port
self.baudrate = baudrate
self.reconnect_interval = reconnect_interval
self.serial_port = None
self.stopped = Event()
self.monitor_thread = Thread(target=self._monitor_device)
self.monitor_thread.daemon = True
def _monitor_device(self):
while not self.stopped.is_set():
try:
if self.serial_port is None or not self.serial_port.isOpen():
self.serial_port = serial.Serial(self.port, self.baudrate)
print(f"连接到 {self.port}") # 或执行你需要的任何初始化
except serial.SerialException:
print(f"无法连接到 {self.port}. 重试中...")
time.sleep(self.reconnect_interval)
def start(self):
self.monitor_thread.start()
def stop(self):
self.stopped.set()
if self.serial_port:
self.serial_port.close()
self.monitor_thread.join()
# 用法示例:
usb_monitor = UsbMonitor(port="COM3", baudrate=115200) # 在 Linux 上,使用 '/dev/ttyUSB0' 等
usb_monitor.start()
# 你的主程序逻辑
try:
while True:
# 使用 usb_monitor.serial_port 发送或接收数据
# ...你的代码...
except KeyboardInterrupt:
usb_monitor.stop()
说明:
-
UsbMonitor
类: - 处理连接、重新连接和断开连接逻辑。
-
使用一个单独的线程 (
_monitor_device
) 来定期检查 USB 设备的状态。 - 如果设备断开连接,它将尝试重新连接。
-
提供
start
和stop
方法来控制监视线程。 -
跨平台兼容性:
-
仅有的特定于平台的部分是串行端口名称(例如,Windows 上为“COM3”,Linux 上为“/dev/ttyUSB0”)。
-
自定义:
-
你可以根据需要调整
reconnect_interval
。 -
在
_monitor_device
中,当建立连接时,你可以添加其他初始化步骤或触发回调。 -
主循环集成:
-
你的主程序逻辑可以继续运行,而监视线程处理连接管理。
-
错误处理:
-
该代码包括基本的错误处理,例如
serial.SerialException
,但这可以根据你的需要进一步增强。
这种方法通过封装连接管理提供了更干净的解决方案,使其更加健壮和用户友好。
标签:python,usb,pyserial From: 78776940