使用 pySerial 在 Python 下重新连接到 USB 端口时,如何避免在 ttyUSB0 和 ttyUSB1 之间切换?
How can I avoid flipping between ttyUSB0 and ttyUSB1 when reconnecting to USB port under Python using pySerial?
我有一个串行 Python 程序,Linux 环境 (Raspbian / Raspberry Pi),它通过 USB 转串行适配器使用串行端口。我需要处理用户拔下USB适配器然后重新插入的情况。
问题是,在重新连接时,ttyUSB0 变为 ttyUSB1,因此不再找到该端口。但是,如果我停止 Python 程序(键盘中断)并再次拔下并重新插入 USB 适配器,则端口将返回 ttyUSB0 (这样我就可以重新开始了).只有当 Python 程序停止时才会发生这种情况。
为了在 ttyUSB0 时使用 ttyUSB1,我在触发器模式下测试了程序(它似乎可以工作)不再找到,反之亦然,使用 ttyUSB0 以防 ttyUSB1 不再找到,等等,但这看起来像一个奇怪的解决方案对我来说。
有没有更好的方法来强制 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)
您可以尝试为该 USB 设备创建一个 udev rule that would create a symbolic link,然后您将能够使用诸如 /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。
Copy/paste 将下面的行写入文件并保存:
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", SYMLINK+="myUSB"
重新启动您的 Raspberry Pi 或拔下 USB 并重新插入。现在应该有一个 /dev/myUSB 条目,您可以像 ttyUSB# 条目一样使用它。
不要忘记在检测到用户拔下USB适配器(读取或写入错误)后立即关闭/dev/ttyUSB0的文件描述符,并且在重新插入之前。
如果正确关闭设备,ttyUSB1设备将永远不会出现。另一方面,在某些情况下,您还可以看到 ttyUSB2、ttyUSB3,依此类推,如果所有先前的 ttyUSBx 因未关闭而被阻止。
如果打开的端口文件在拔出时关闭(或在错误处理程序中),则端口名称在后续连接 USB 设备时不会更改。如果保持打开状态,那么每次都会创建不同的名称。
我有一个串行 Python 程序,Linux 环境 (Raspbian / Raspberry Pi),它通过 USB 转串行适配器使用串行端口。我需要处理用户拔下USB适配器然后重新插入的情况。
问题是,在重新连接时,ttyUSB0 变为 ttyUSB1,因此不再找到该端口。但是,如果我停止 Python 程序(键盘中断)并再次拔下并重新插入 USB 适配器,则端口将返回 ttyUSB0 (这样我就可以重新开始了).只有当 Python 程序停止时才会发生这种情况。
为了在 ttyUSB0 时使用 ttyUSB1,我在触发器模式下测试了程序(它似乎可以工作)不再找到,反之亦然,使用 ttyUSB0 以防 ttyUSB1 不再找到,等等,但这看起来像一个奇怪的解决方案对我来说。
有没有更好的方法来强制 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)
您可以尝试为该 USB 设备创建一个 udev rule that would create a symbolic link,然后您将能够使用诸如 /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。
Copy/paste 将下面的行写入文件并保存:
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", SYMLINK+="myUSB"
重新启动您的 Raspberry Pi 或拔下 USB 并重新插入。现在应该有一个 /dev/myUSB 条目,您可以像 ttyUSB# 条目一样使用它。
不要忘记在检测到用户拔下USB适配器(读取或写入错误)后立即关闭/dev/ttyUSB0的文件描述符,并且在重新插入之前。
如果正确关闭设备,ttyUSB1设备将永远不会出现。另一方面,在某些情况下,您还可以看到 ttyUSB2、ttyUSB3,依此类推,如果所有先前的 ttyUSBx 因未关闭而被阻止。
如果打开的端口文件在拔出时关闭(或在错误处理程序中),则端口名称在后续连接 USB 设备时不会更改。如果保持打开状态,那么每次都会创建不同的名称。