在机器人设备调试过程中,我们经常会用到通过 USB 转串口连接的夹爪、传感器或其他外设。

系统默认会将这些设备识别为 /dev/ttyUSB0/dev/ttyUSB1 等。但是:

  • 每次插拔设备,编号可能会变化,代码里硬编码 /dev/ttyUSB0 等名称会失效。
  • 每次使用前都需要 chmod 777 /dev/ttyUSB0 来获取读写权限。

因此希望通过给每个设备分配一个 固定且自定义的端口名(例如 /dev/left_gripper/dev/right_gripper),这样无论插拔顺序如何,代码都能稳定识别设备。

1. 查询设备信息

首先用 lsusb 查看设备的 厂商 ID(idVendor)产品 ID(idProduct)

可以拔插一次观察多出来的那一行就是夹爪设备,例如我的设备 ID 是 0403:6001,分别代表 idVendor:idProduct

1
Bus 001 Device 005: ID 0403:6001 Future Technology Devices International, Ltd FT232 Serial (UART) IC

2. 单设备情况

创建并编辑配置文件:

1
sudo vim /etc/udev/rules.d/usb.rules

写入规则,例如:

1
KERNEL=="ttyUSB*", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", MODE:="0777", SYMLINK+="gripper"

其中

  • KERNEL:不修改
  • ATTRS{idVendor}:填写 ID 冒号前的部分
  • ATTRS{idProduct}:填写 ID 冒号后的部分
  • MODE:默认设置为 0777 即可,可读可写可执行
  • SYMLINK:自定义,也就是想要将 ttyUSB0 改成什么一个固定的名字

编辑完成后,重启 udev 服务:

1
2
service udev reload
service udev restart

重新插拔设备,然后 ls /dev/,就可以看到自己设置的端口名出现。

1
/dev/gripper -> ttyUSB0

之后你就可以直接在代码里用 /dev/gripper

3. 如果连接了两台同样的设备

多个同型号设备可能会有相同的 idVendor:idProduct,这时需要进一步区分。

大多数芯片带有唯一的 序列号,可以用以下命令查看:

1
2
3
# 将 /dev/ttyUSB0 和 /dev/ttyUSB1 改成你要区分的两个设备
udevadm info -a -n /dev/ttyUSB0 | grep '{serial}' | head -n 1
udevadm info -a -n /dev/ttyUSB1 | grep '{serial}' | head -n 1

你会看到类似输出:

1
2
ATTRS{serial}=="BG00VUIX"
ATTRS{serial}=="BG00VVHF"

这样我们就能通过 序列号 唯一标识不同的设备。

在规则中写入ATTRS{serial}=="BG00VUIX",,例如:

1
sudo vim /etc/udev/rules.d/usb.rules
1
2
3
4
5
# 左手夹爪
KERNEL=="ttyUSB*", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="BG00VUIX", MODE:="0777", SYMLINK+="left_gripper"

# 右手夹爪
KERNEL=="ttyUSB*", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="BG00VVHF", MODE:="0777", SYMLINK+="right_gripper"

编辑完成后,重启 udev 服务:

1
2
service udev reload
service udev restart

重新插拔设备,然后 ls /dev/,就可以看到自己设置的端口名出现。

1
/dev/gripper -> ttyUSB0

之后你就可以直接在代码里用 /dev/gripper