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

时间:2018-01-20 12:37:32

标签: python raspberry-pi raspbian pyserial

我有一个串行Python程序,Linux环境(Raspbian / Raspberry Pi),它通过USB和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)

3 个答案:

答案 0 :(得分:3)

您可以尝试创建一个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"

重新启动Pi或拔下USB插头并重新插入。现在应该有一个/ dev / myUSB条目,您可以使用与ttyUSB#条目相同的方式。

答案 1 :(得分:0)

一旦检测到用户拔出USB适配器(读取或写入错误),并且在重新插入之前,不要忘记关闭/ dev / ttyUSB0的文件描述符。 如果正确关闭设备,则ttyUSB1设备将永远不会出现。另一方面,如果以前的所有ttyUSBx由于未关闭而被阻塞,那么在某些情况下您还可以看到ttyUSB2,ttyUSB3等。

答案 2 :(得分:0)

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