如何动态获取RFID阅读器所连接串口的分配名称
这个问题我之前帮不少朋友处理过,本质是系统按USB设备的连接顺序分配ttyUSBx编号,重启或重新插拔设备时编号就会变动。下面给你几个靠谱的解决方案,按推荐程度排序:
1. 用udev规则创建固定设备别名(最推荐)
这是最稳定的方案,通过设备的唯一硬件标识(比如厂商ID、产品ID、序列号)绑定固定名称,不管怎么插拔都不会变。
第一步:获取设备硬件信息
插好RFID阅读器,运行以下命令:lsusb找到你的设备行,比如类似:
Bus 001 Device 004: ID 1a86:7523 QinHeng Electronics CH340 serial converter,这里的1a86是VID(厂商ID),7523是PID(产品ID)。如果有多个同型号设备,还需要序列号,运行:
udevadm info -a -n /dev/ttyUSB0 | grep -E 'ATTR{idVendor}|ATTR{idProduct}|ATTR{serial}'把这三个信息记下来。
第二步:创建udev规则文件
运行命令创建规则文件:sudo nano /etc/udev/rules.d/99-rfid-reader.rules写入以下内容(替换成你自己的VID、PID、serial):
SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", ATTRS{serial}=="ABC123", SYMLINK+="rfid_reader"其中
SYMLINK+="rfid_reader"是你自定义的固定名称,比如rfid_reader,之后就可以用/dev/rfid_reader访问设备。第三步:生效规则
运行命令重载udev规则:sudo udevadm control --reload-rules && sudo udevadm trigger之后重启树莓派,就能用固定名称访问设备了,代码里直接写这个路径即可。
2. 按USB物理端口绑定固定名称
如果不需要区分同型号设备,只是想固定某个USB口的设备名,也可以用udev规则绑定物理端口:
第一步:获取设备的物理路径
运行命令:udevadm info -a -n /dev/ttyUSB0 | grep 'ATTR{devpath}'比如得到
ATTR{devpath}=="1.2",对应的物理端口标识是1-1.2(前面加总线编号,树莓派一般是1)。第二步:创建规则文件
同样编辑99-rfid-reader.rules文件,写入:SUBSYSTEM=="tty", KERNELS=="1-1.2", SYMLINK+="rfid_reader"重载规则后,这个USB口插的设备就会被命名为
/dev/rfid_reader。
3. 在代码中自动检测可用串口
如果不想修改系统配置,也可以在代码里做动态检测,自动找到RFID阅读器的串口。以Python为例:
import serial from serial.tools.list_ports import comports def find_rfid_port(): ports = comports() for port in ports: # 优先通过VID/PID过滤,更准确 if port.vid == 0x1a86 and port.pid == 0x7523: return port.device # 无VID/PID时,尝试打开串口测试通信 try: ser = serial.Serial(port.device, baudrate=9600, timeout=1) # 发送测试指令(根据你的阅读器协议调整) ser.write(b'AT\r\n') response = ser.readline() if response: ser.close() return port.device ser.close() except Exception as e: continue return None # 调用示例 rfid_port = find_rfid_port() if rfid_port: print(f"找到RFID阅读器:{rfid_port}") # 后续用这个端口操作设备 else: print("未找到可用的RFID阅读器")
这种方法适合动态适配场景,但不如udev规则稳定,若有其他USB串口设备可能会误判。
内容的提问来源于stack exchange,提问作者Phil Winston

