Подключение нескольких Arduino под Linux


Бывает, возникает ситуация, когда к ПК или одноплатному компьютеру (например, Raspberry Pi) под управлением ОС Linux требуется подключить несколько контроллеров Arduino (или несколько переходников USB2COM), причём нужно точно знать — кто из них кто.
Здесь нам на помощь приходит менеджер udev.
Порядок действий следующий:
1. подключаем в USB один из контроллеров Arduino/CraftDuino.
2. смотрим как он определился:
ls /dev/ttyUSB*
— если подключён только один переходник USB2COM, то устройство должно быть только одно — /dev/ttyUSB0
3. смотрим его параметры команды:
udevadm info --name=/dev/ttyUSB0 --attribute-walk

для переходника на базе FTDI, получим на выходе что-то вроде:
looking at device '/devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0/ttyUSB0/tty/ttyUSB0':
    KERNEL=="ttyUSB0"
    SUBSYSTEM=="tty"
    DRIVER==""

  looking at parent device '/devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0/ttyUSB0':
    KERNELS=="ttyUSB0"
    SUBSYSTEMS=="usb-serial"
    DRIVERS=="ftdi_sio"
    ATTRS{latency_timer}=="1"
    ATTRS{port_number}=="0"

  looking at parent device '/devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0':
    KERNELS=="2-2:1.0"
    SUBSYSTEMS=="usb"
    DRIVERS=="ftdi_sio"
    ATTRS{bInterfaceNumber}=="00"
    ATTRS{bAlternateSetting}==" 0"
    ATTRS{bNumEndpoints}=="02"
    ATTRS{bInterfaceClass}=="ff"
    ATTRS{bInterfaceSubClass}=="ff"
    ATTRS{bInterfaceProtocol}=="ff"
    ATTRS{supports_autosuspend}=="1"
    ATTRS{interface}=="FT232R USB UART"

  looking at parent device '/devices/pci0000:00/0000:00:1d.0/usb2/2-2':
    KERNELS=="2-2"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{configuration}==""
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bmAttributes}=="a0"
    ATTRS{bMaxPower}==" 90mA"
    ATTRS{urbnum}=="16"
    ATTRS{idVendor}=="0403"
    ATTRS{idProduct}=="6001"
    ATTRS{bcdDevice}=="0600"
    ATTRS{bDeviceClass}=="00"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bMaxPacketSize0}=="8"
    ATTRS{speed}=="12"
    ATTRS{busnum}=="2"
    ATTRS{devnum}=="12"
    ATTRS{devpath}=="2"
    ATTRS{version}==" 2.00"
    ATTRS{maxchild}=="0"
    ATTRS{quirks}=="0x0"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{authorized}=="1"
    ATTRS{manufacturer}=="FTDI"
    ATTRS{product}=="FT232R USB UART"
    ATTRS{serial}=="A6007Jii"

  looking at parent device '/devices/pci0000:00/0000:00:1d.0/usb2':
    KERNELS=="usb2"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{configuration}==""
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bmAttributes}=="e0"
    ATTRS{bMaxPower}=="  0mA"
    ATTRS{urbnum}=="230"
    ATTRS{idVendor}=="1d6b"
    ATTRS{idProduct}=="0001"
    ATTRS{bcdDevice}=="0300"
    ATTRS{bDeviceClass}=="09"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{speed}=="12"
    ATTRS{busnum}=="2"
    ATTRS{devnum}=="1"
    ATTRS{devpath}=="0"
    ATTRS{version}==" 1.10"
    ATTRS{maxchild}=="2"
    ATTRS{quirks}=="0x0"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{authorized}=="1"
    ATTRS{manufacturer}=="Linux 3.0.3-std-def-alt0.M60P.1 uhci_hcd"
    ATTRS{product}=="UHCI Host Controller"
    ATTRS{serial}=="0000:00:1d.0"
    ATTRS{authorized_default}=="1"

  looking at parent device '/devices/pci0000:00/0000:00:1d.0':
    KERNELS=="0000:00:1d.0"
    SUBSYSTEMS=="pci"
    DRIVERS=="uhci_hcd"
    ATTRS{vendor}=="0x8086"
    ATTRS{device}=="0x8114"
    ATTRS{subsystem_vendor}=="0x8086"
    ATTRS{subsystem_device}=="0x8119"
    ATTRS{class}=="0x0c0300"
    ATTRS{irq}=="5"
    ATTRS{local_cpus}=="ffffffff,ffffffff"
    ATTRS{local_cpulist}=="0-63"
    ATTRS{dma_mask_bits}=="32"
    ATTRS{consistent_dma_mask_bits}=="32"
    ATTRS{enable}=="1"
    ATTRS{broken_parity_status}=="0"
    ATTRS{msi_bus}==""

  looking at parent device '/devices/pci0000:00':
    KERNELS=="pci0000:00"
    SUBSYSTEMS==""
    DRIVERS==""


обращаем внимание на строчку
ATTRS{serial}=="A6007Jii"


остаётся только создать конфигурационный файл для менеджера udev
в /etc/udev/rules.d
помещаем файл 10-local.rules вида:
для Debian (6):
BUS=="usb", SYSFS{idProduct}=="6001", SYSFS{idVendor}=="0403", SYSFS{serial}=="A6007Jii", NAME="myCraftDuino"

для Ubuntu (12.04):
SUBSYSTEMS=="usb", ATTRS{idProduct}=="6001", ATTRS{idVendor}=="0403", ATTRS{serial}=="A6007Jii", NAME="myCraftDuino"


Отсоедините устройство от USB и подключите его снова — теперь оно должно определиться как /dev/myCraftDuino, что нам и требовалось.
Остаётся проделать эти шаги для всех требуемых USB2COM переходников и дать им свои уникальные имена.

Чтобы у пользователя не было проблем с доступом к устройству — его нужно добавить в группу доступа на данное устройство:
по-умолчанию группа: dialout

sudo usermod -aG dialout <user_name>



Ссылки:
ru.wikipedia.org/wiki/Udev
wiki.debian.org/udev
Giving An FTDI Serial Port A Persistent Device Node
Mapping FTDI to files with udev
  • +1
  • 30 июня 2013, 13:43
  • admin

Комментарии (2)

RSS свернуть / развернуть
+
+1
Решал аналогичную проблему с USB-GPS приемником, idVendor и idProduct оказалось удобнее взять в
$ lsusb
Bus 001 Device 009: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port

Для USB GPS на Raspbian сработала такая строчка:
ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", NAME="usbgps"

Хотя старое имя остается:
lrwxrwxrwx 1 root root           6 Янв  1  1970 gps0 -> usbgps
crw------- 1 root root    188,   0 Янв  1  1970 ttyUSB0


Кстати, оказалось, что (по крайней мере с Си) можно работать прямо с /dev/gps0 и не ломать голову с заменами в /dev/ttyUSBXXX
avatar

Bender

  • 12 января 2015, 15:12
+
+1
Поправка: gps0 тоже может съехать на gps1 :), так что udev все равно надо настраивать.
avatar

Bender

  • 12 января 2015, 15:29

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.