在使用pySerial重新连接到Python下的USB端口时,如何避免在ttyUSB0和ttyUSB1之间翻转?



我有一个串行Python程序,Linux环境(Raspbian/Raspberry Pi),它通过USB到串行适配器使用串行端口。我需要处理用户拔下 USB 适配器然后重新插入的情况。

问题是,在重新连接时,ttyUSB0 变为ttyUSB1,因此不再找到端口。但是,如果我停止 Python 程序(键盘中断)并再次拔下并重新插入 USB 适配器,则端口将返回到ttyUSB0(因此我可以重新开始)。这只有在 Python 程序停止时才会发生。

我在触发器模式下测试了该程序(它似乎正在工作),以便在不再找到ttyUSB0时使用 ttyUSB1,反之亦然,在不再找到ttyUSB1的情况下使用ttyUSB0等,但这对我来说似乎是一个奇怪的解决方案。

有没有更好的方法可以强制pySerial在出现错误时"忘记"它曾经连接到ttyUSB0,并在程序仍在运行时将当前端口释放到系统?

这是一个有效的触发器测试程序:

import serial
import time
p = "/dev/ttyUSB0"
while True:
error_flag = False
try:
s = serial.Serial(port=p, baudrate=9600, bytesize=8, parity="N", stopbits=1, timeout=None, xonxoff=False, rtscts=False, write_timeout=None, dsrdtr=False, inter_byte_timeout=None)
except Exception as e:
error_flag = True
if "ttyUSB0" in str(e):
p = "/dev/ttyUSB1"
print ("port is now", p)
elif "ttyUSB1" in str(e):
p = "/dev/ttyUSB0"
print ("port is now", p)
else:
print (e)   # none of the above
# if not error_flag, do whatever, etc.
time.sleep(1)

您可以尝试创建一个 udev 规则,该规则将创建指向该 USB 设备的符号链接,然后您将能够使用类似/dev/myUSB的东西,该特定 USB 设备将始终保持不变。

首先,您需要找到USB驱动器的一些标识信息。键入lsusb应显示一些信息,如下所示:

Bus 001 Device 004: ID 0403:6001 Future Technology Devices International

在此示例中,0403 是供应商ID,6001 是产品 ID

创建一个名为99_usbdevice.rules的文件(我认为名称无关紧要,只需目录):

sudo nano /etc/udev/rules.d/99_usbdevices.rules

请注意,上面的目录可能特定于 Raspbian。

将以下行复制/粘贴到文件中并保存:

SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", SYMLINK+="myUSB"

重新启动树莓派或拔下 USB 并重新插入。现在应该有一个/dev/myUSB条目,你可以像使用ttyUSB#条目一样使用它。

如果打开的端口文件在拔出时(或在错误处理程序上)关闭,则端口名称在 USB 设备的后续连接时不会更改。如果保持打开状态,那么它每次都会创建一个不同的名称。

一旦检测到用户拔下 USB 适配器(读取或写入错误),并且重新插入之前,不要忘记关闭/dev/ttyUSB0的文件描述符。

如果正确关闭设备,ttyUSB1设备将永远不会出现。另一方面,在某些情况下,您还可以看到ttyUSB2,ttyUSB3等,如果所有以前的ttyUSBx都被阻止,因为未关闭

最新更新