В Linux, как определить несколько Arduinos, подключенных через USB?

17

Если у меня есть несколько Arduinos, подключенных через USB к компьютеру Linux, и они отображаются как

  • / TTY / ACM0
  • / TTY / ACM1
  • / TTY / ACM2

Как я могу определить, какой Arduino какой, не подключаясь к ним через последовательное соединение ? Есть ли на Arduino серийный номер или уникальный идентификатор?

Спасибо за уделенное время.

Ситуация: Uno R3, Mega, Leonardo с / ttyACM [1,2,3]

Вывод lsusb с устройствами в указанном выше порядке:

...
Автобус 001 Устройство 011: ID 2341: 0043
Автобус 001 Устройство 013: ID 2341: 8036
...
Автобус 001 Устройство 014: ID 2341: 0042

lsusb -d vendor: устройство показывает -vvv для каждого

Организация Объединенных Наций

Автобус 001 Устройство 014: ID 2341: 0042
Дескриптор устройства:
  Длина 18
  bDescriptorType 1
  bcdUSB 1.10
  bDeviceClass 2 Communications
  bDeviceSubClass 0
  bDeviceProtocol 0
  bMaxPacketSize0 8
  idVendor 0x2341
  idProduct 0x0042
  bcdDevice 0.01
  iManufacturer 1 Arduino (www.arduino.cc)
  iProduct 2
  iSerial 220 55330313735351910141
  bNumConfigurations 1
  Дескриптор конфигурации:
    Длина 9
    bDescriptorType 2
    wTotalLength 62
    bNumInterfaces 2
    bConfigurationValue 1
    iConfiguration 0
    bmAttributes 0xc0
      Самостоятельное питание
    MaxPower 100 мА
    Дескриптор интерфейса:
      Длина 9
      bDescriptorType 4
      bInterfaceNumber 0
      bAlternateSetting 0
      bNumEndpoints 1
      bInterfaceClass 2 Communications
      bInterfaceSubClass 2 Abstract (модем)
      AT-команды bInterfaceProtocol 1 (v.25ter)
      iInterface 0
      Заголовок CDC:
        bcdCDC 10.01
      CDC ACM:
        bmCapabilities 0x06
          посылает перерыв
          линейное кодирование и серийный статус
      CDC Union:
        bMasterInterface 0
        bSlaveInterface 1
      Описатель конечной точки:
        Длина 7
        bDescriptorType 5
        bEndpointAddress 0x82 EP 2 IN
        bmAttributes 3
          Тип передачи Прерывание
          Тип синхронизации Нет
          Данные типа использования
        wMaxPacketSize 0x0008 1x 8 байтов
        bInterval 255
    Дескриптор интерфейса:
      Длина 9
      bDescriptorType 4
      bInterfaceNumber 1
      bAlternateSetting 0
      bNumEndpoints 2
      Данные CDC bInterfaceClass 10
      bInterfaceSubClass 0 Не используется
      bInterfaceProtocol 0
      iInterface 0
      Описатель конечной точки:
        Длина 7
        bDescriptorType 5
        bEndpointAddress 0x04 EP 4 OUT
        bmAttributes 2
          Тип передачи Массовая
          Тип синхронизации Нет
          Данные типа использования
        wMaxPacketSize 0x0040 1x 64 байта
        bInterval 1
      Описатель конечной точки:
        Длина 7
        bDescriptorType 5
        bEndpointAddress 0x83 EP 3 IN
        bmAttributes 2
          Тип передачи Массовая
          Тип синхронизации Нет
          Данные типа использования
        wMaxPacketSize 0x0040 1x 64 байта
        bInterval 1
Состояние устройства: 0x0000
  (Питание от шины)

Леонардо:

Автобус 001 Устройство 013: ID 2341: 8036
Дескриптор устройства:
  Длина 18
  bDescriptorType 1
  bcdUSB 2.00
  bDeviceClass 0 (определен на уровне интерфейса)
  bDeviceSubClass 0
  bDeviceProtocol 0
  bMaxPacketSize0 64
  idVendor 0x2341
  idProduct 0x8036
  bcdDevice 1.00
  ООО «iManufacturer 1 Ардуино»
  iProduct 2 Arduino Leonardo
  iSerial 0
  bNumConfigurations 1
  Дескриптор конфигурации:
    Длина 9
    bDescriptorType 2
    wTotalLength 100
    bNumInterfaces 3
    bConfigurationValue 1
    iConfiguration 0
    bmAttributes 0x80
      (Питание от шины)
    MaxPower 500 мА
    Ассоциация интерфейсов:
      Длина 8
      bDescriptorType 11
      bFirstInterface 0
      bInterfaceCount 2
      Связь bFunctionClass 2
      bFunctionSubClass 2 Abstract (модем)
      AT-команды bFunctionProtocol 1 (v.25ter)
      iFunction 0
    Дескриптор интерфейса:
      Длина 9
      bDescriptorType 4
      bInterfaceNumber 0
      bAlternateSetting 0
      bNumEndpoints 1
      bInterfaceClass 2 Communications
      bInterfaceSubClass 2 Abstract (модем)
      bInterfaceProtocol 0 Нет
      iInterface 0
      Заголовок CDC:
        bcdCDC 1.10
      Управление вызовами CDC:
        bmCapabilities 0x01
          управление звонками
        bDataInterface 1
      CDC ACM:
        bmCapabilities 0x06
          посылает перерыв
          линейное кодирование и серийный статус
      CDC Union:
        bMasterInterface 0
        bSlaveInterface 1
      Описатель конечной точки:
        Длина 7
        bDescriptorType 5
        bEndpointAddress 0x81 EP 1 IN
        bmAttributes 3
          Тип передачи Прерывание
          Тип синхронизации Нет
          Данные типа использования
        wMaxPacketSize 0x0040 1x 64 байта
        bInterval 0
      Описатель конечной точки:
        Длина 7
        bDescriptorType 5
        bEndpointAddress 0x83 EP 3 IN
        bmAttributes 2
          Тип передачи Массовая
          Тип синхронизации Нет
          Данные типа использования
        wMaxPacketSize 0x0040 1x 64 байта
        bInterval 0
    Дескриптор интерфейса:
      Длина 9
      bDescriptorType 4
      bInterfaceNumber 2
      bAlternateSetting 0
      bNumEndpoints 1
      bInterfaceClass 3 устройство интерфейса пользователя
      bInterfaceSubClass 0 Нет подкласса
      bInterfaceProtocol 0 Нет
      iInterface 0
        HID Device Descriptor:
          Длина 9
          bDescriptorType 33
          bcdHID 1.01
          bCountryCode 0 не поддерживается
          bNumDescriptors 1
          Отчет bDescriptorType 34
          wDescriptorLength 101
          Дескриптор отчета: (длина 101)
            Элемент (глобальный): страница использования, данные = [0x01] 1
                            Общие элементы управления рабочим столом
            Элемент (локальный): использование, данные = [0x02] 2
                            мышь
            Элемент (основной): коллекция, данные = [0x01] 1
                            заявка
            Элемент (локальный): использование, данные = [0x01] 1
                            Указатель
            Элемент (основной): коллекция, данные = [0x00] 0
                            физический
            Элемент (глобальный): идентификатор отчета, данные = [0x01] 1
            Элемент (глобальный): страница использования, данные = [0x09] 9
                            Кнопки
            Элемент (локальный): минимальное использование, данные = [0x01] 1
                            Кнопка 1 (основной)
            Элемент (локальный): максимум использования, данные = [0x03] 3
                            Кнопка 3 (третичная)
            Элемент (глобальный): логический минимум, данные = [0x00] 0
            Элемент (глобальный): логический максимум, данные = [0x01] 1
            Элемент (глобальный): количество отчетов, данные = [0x03] 3
            Элемент (глобальный): размер отчета, данные = [0x01] 1
            Элемент (основной): вход, данные = [0x02] 2
                            Переменная данных Абсолютная No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Битовое поле
            Элемент (глобальный): количество отчетов, данные = [0x01] 1
            Элемент (глобальный): размер отчета, данные = [0x05] 5
            Элемент (основной): вход, данные = [0x03] 3
                            Постоянная переменная Абсолютная No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Битовое поле
            Элемент (глобальный): страница использования, данные = [0x01] 1
                            Общие элементы управления рабочим столом
            Элемент (локальный): использование, данные = [0x30] 48
                            Направление-X
            Элемент (локальный): использование, данные = [0x31] 49
                            Направление-Y
            Элемент (локальный): использование, данные = [0x38] 56
                            Рулевое колесо
            Элемент (глобальный): логический минимум, данные = [0x81] 129
            Элемент (глобальный): логический максимум, данные = [0x7f] 127
            Элемент (глобальный): размер отчета, данные = [0x08] 8
            Элемент (глобальный): количество отчетов, данные = [0x03] 3
            Элемент (основной): вход, данные = [0x06] 6
                            Относительная переменная данных No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Битовое поле
            Элемент (основной): окончание сбора, данные = нет
            Элемент (основной): окончание сбора, данные = нет

            ......

      Описатель конечной точки:
        Длина 7
        bDescriptorType 5
        bEndpointAddress 0x84 EP 4 IN
        bmAttributes 3
          Тип передачи Прерывание
          Тип синхронизации Нет
          Данные типа использования
        wMaxPacketSize 0x0040 1x 64 байта
        bInterval 1
Состояние устройства: 0x0000
  (Питание от шины)

И мега256:

Автобус 001 Устройство 014: ID 2341: 0042
Дескриптор устройства:
  Длина 18
  bDescriptorType 1
  bcdUSB 1.10
  bDeviceClass 2 Communications
  bDeviceSubClass 0
  bDeviceProtocol 0
  bMaxPacketSize0 8
  idVendor 0x2341
  idProduct 0x0042
  bcdDevice 0.01
  iManufacturer 1 Arduino (www.arduino.cc)
  iProduct 2
  iSerial 220 55330313735351910141
  bNumConfigurations 1
  Дескриптор конфигурации:
    Длина 9
    bDescriptorType 2
    wTotalLength 62
    bNumInterfaces 2
    bConfigurationValue 1
    iConfiguration 0
    bmAttributes 0xc0
      Самостоятельное питание
    MaxPower 100 мА
    Дескриптор интерфейса:
      Длина 9
      bDescriptorType 4
      bInterfaceNumber 0
      bAlternateSetting 0
      bNumEndpoints 1
      bInterfaceClass 2 Communications
      bInterfaceSubClass 2 Abstract (модем)
      AT-команды bInterfaceProtocol 1 (v.25ter)
      iInterface 0
      Заголовок CDC:
        bcdCDC 10.01
      CDC ACM:
        bmCapabilities 0x06
          посылает перерыв
          линейное кодирование и серийный статус
      CDC Union:
        bMasterInterface 0
        bSlaveInterface 1
      Описатель конечной точки:
        Длина 7
        bDescriptorType 5
        bEndpointAddress 0x82 EP 2 IN
        bmAttributes 3
          Тип передачи Прерывание
          Тип синхронизации Нет
          Данные типа использования
        wMaxPacketSize 0x0008 1x 8 байтов
        bInterval 255
    Дескриптор интерфейса:
      Длина 9
      bDescriptorType 4
      bInterfaceNumber 1
      bAlternateSetting 0
      bNumEndpoints 2
      Данные CDC bInterfaceClass 10
      bInterfaceSubClass 0 Не используется
      bInterfaceProtocol 0
      iInterface 0
      Описатель конечной точки:
        Длина 7
        bDescriptorType 5
        bEndpointAddress 0x04 EP 4 OUT
        bmAttributes 2
          Тип передачи Массовая
          Тип синхронизации Нет
          Данные типа использования
        wMaxPacketSize 0x0040 1x 64 байта
        bInterval 1
      Описатель конечной точки:
        Длина 7
        bDescriptorType 5
        bEndpointAddress 0x83 EP 3 IN
        bmAttributes 2
          Тип передачи Массовая
          Тип синхронизации Нет
          Данные типа использования
        wMaxPacketSize 0x0040 1x 64 байта
        bInterval 1
Состояние устройства: 0x0000
  (Питание от шины)
влад б.
источник
lsusb -vvvговорит?
Игнасио Васкес-Абрамс
Можете ли вы отключить один и посмотреть, какой из них исчезает?
Анонимный Пингвин
1
Не совсем, я хочу сделать это для выносного сенсорного массива на солнечной батарее, который будет очень далеко для кого-то, когда он перезагружается.
влад б.
Игнасио Васкес-Абрамс - как я могу отобразить информацию из lsusb -vvv в / dev / ttyACM <x>? Есть ли что-то в выводе lsusb, который я могу проанализировать? Спасибо за идею!
влад б.
У вас есть другой Arduino, с которым вы можете сравнить выход?
Игнасио Васкес-Абрамс

Ответы:

6

Предполагая, что ваш дистрибутив использует udev:

udevadm info --query=all --name=/dev/ttyACM0

Возможно, вам понадобятся права суперпользователя (sudo / su). Это выведет список информации как это:

P: /devices/pci0000:00/0000:00:1d.2/usb4/4-2/4-2:1.0/tty/ttyACM0
N: ttyACM0
S: serial/by-id/usb-Dean_Camera_LUFA_USB-RS232_Adapter_74133353537351403012-if00
S: serial/by-path/pci-0000:00:1d.2-usb-0:2:1.0
E: DEVLINKS=/dev/serial/by-id/usb-Dean_Camera_LUFA_USB-RS232_Adapter_74133353537351403012-if00 /dev/serial/by-path/pci-0000:00:1d.2-usb-0:2:1.0
E: DEVNAME=/dev/ttyACM0
E: DEVPATH=/devices/pci0000:00/0000:00:1d.2/usb4/4-2/4-2:1.0/tty/ttyACM0
E: ID_BUS=usb
E: ID_MM_CANDIDATE=1
E: ID_MODEL=LUFA_USB-RS232_Adapter
E: ID_MODEL_ENC=LUFA\x20USB-RS232\x20Adapter
E: ID_MODEL_FROM_DATABASE=Uno R3 (CDC ACM)
E: ID_MODEL_ID=0043
E: ID_PATH=pci-0000:00:1d.2-usb-0:2:1.0
E: ID_PATH_TAG=pci-0000_00_1d_2-usb-0_2_1_0
E: ID_REVISION=0001
E: ID_SERIAL=Dean_Camera_LUFA_USB-RS232_Adapter_74133353537351403012
E: ID_SERIAL_SHORT=74133353537351403012
E: ID_TYPE=generic
E: ID_USB_DRIVER=cdc_acm
E: ID_USB_INTERFACES=:020201:0a0000:
E: ID_USB_INTERFACE_NUM=00
E: ID_VENDOR=Dean_Camera
E: ID_VENDOR_ENC=Dean\x20Camera
E: ID_VENDOR_FROM_DATABASE=Arduino SA
E: ID_VENDOR_ID=2341
E: MAJOR=166
E: MINOR=0
E: SUBSYSTEM=tty
E: UDEV_LOG=3
E: USEC_INITIALIZED=751387324986

Это для Uno с модифицированной прошивкой на atmega16u2 (от usb к serial). Интересующие линии, вероятно, ID_MODEL_ID и ID_MODEL_FROM_DATABASE.

user2973
источник
Спасибо. В этом случае я использую OpenWrt с hotplug2 по умолчанию, но я попытаюсь переключиться на udev и проверить это.
влад б.
5

Вы можете добавить псевдоним для каждого. Тогда вы знаете, что есть что. Вот хороший учебник о том, как это настроить.

Вот фрагмент, который я написал на основе учебника. В приведенном ниже примере я использую переходник FTDI RS232RL USB-Serial, который, как я полагаю, используется и Arduino.

  1. Чтобы назначить псевдоним устройству USB-Serial, нам нужно найти некоторую информацию об устройстве
  2. Подключите USB. Это предполагает, что вы уже установили драйверы для этого использования устройства, и устройство отображается при наборе:

lsusb

  1. Нам понадобится следующее. Идентификатор продавца б. Идентификатор продукта c. Серийный номер устройства
  2. Для этого нужно немного поохотиться. Все ваши устройства регистрируют записи в «/ var / log / messages».

Поэтому мы можем прочитать этот файл и найти правильный USB:

grep "ftdi" /var/log/messages

Вы также можете использовать «USB»

  1. Это найти все сообщения с тегом ftdi:

  2. Рядом с ftdi_sio есть число вроде 1-1.2. Это устройство USB

grep "usb 1-1.2" /var/log/messages

Или вы можете использовать:

dmesg | grep "usb 1-1.3"
  1. Это дает нам всю необходимую нам информацию:

USB Alias

  1. Теперь, имея список серийных номеров, давайте создадим набор правил UDEV, который создаст красивую символическую ссылку для каждого из этих устройств. Правила UDEV обычно разбросаны по многим файлам в /etc/udev/rules.d. Создайте новый файл с именем 99-usb-serial.rules и вставьте в него следующие строки:

В этом примере мой псевдоним называется lcdbox.

SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="A601ERJJ", SYMLINK+="lcdbox"
  1. SYMLINK - это имя вашего псевдонима. В этом случае мой псевдоним - lcdbox.
  2. Сохраните файл и введите

    sudo udevadm control --reload-rules

  3. Тип

    ls –l / dev / lcdbox

lrwxrwxrwx 1 root root 7 января 1 1970 г. / dev / lcdbox -> ttyUSB0

  1. Это показывает, что мой псевдоним lcdbox сопоставлен с ttyUSB0.
PhillyNJ
источник
4

Это довольно просто! Вы должны настроить прошивку ftdi chips и добавить правило udev:

Сначала получите ftdi_eepromчерез apt-getили из источников. Определите ваше устройство через lsusb и получите идентификатор:

lsusb

Шина 001 Устройство 005: ID 0403: 6001 Компания Future Technology Devices International, Ltd FT232 Serial (UART)
....

Подготовьте конфиг и убедитесь, что vendor_idи product_idсовпадаете. Настройте строки в Stringsразделе, чтобы получить уникальный идентификатор для вашего устройства.

vendor_id = 0x0403 # идентификатор поставщика
product_id = 0x6001 # идентификатор продукта

max_power = 50 # Макс. Потребляемая мощность: значение * 2 мА. Используйте 0, если self_powered = true.

###########
# Строки #
########### 
factory = "FTDI" # Производитель
product = "Arduino Nano" # Продукт
serial = "arduino1" # Serial

###########
# Параметры #
###########
self_powered = false # Выключите это для питания от шины
remote_wakeup = false # Включите это для функции удаленного пробуждения
use_serial = true # Использовать строку серийного номера

# Обычно нет необходимости менять один из этих флагов
# BM_type_chip = true # Все новые чипы относятся к типу BM
in_is_isochronous = false # Конечная точка является изохронной
out_is_isochronous = false # Конечная точка выхода является изохронной
suspend_pull_downs = false # Включить приостановить раскрывающиеся списки для снижения мощности
change_usb_version = false # Изменить версию USB
usb_version = 0x0200 # Используется только при включенном change_usb_version

########
# Разное #
########

filename = "eeprom.old" # Имя файла, оставьте пустым, чтобы пропустить запись файла
cbus0 = RXLED #
cbus1 = # линии TXLED

Дамп текущей ftdi-прошивки:

ftdi_eeprom --read-eprom

Эта команда создает ${pwd}/eeprom.old, которая содержит текущую прошивку на ftdi. Сделайте резервную копию этого файла, прежде чем продолжить , потому что во flash-eepromвремя файла перезаписывается. После резервного копирования прошить ftdi:

ftdi_eeprom --flash-eeprom myconfig.conf

Теперь создайте правило udev, вот так

SUBSYSTEMS=="usb", ATTRS{idProduct}=="6001", ATTRS{idVendor}=="0403", SYMLINK+="$attr{serial}", OWNER="bananapi", GROUP="pi", MODE="0777"

в /etc/udev/rules.d/90-arduino-usb.rulesи рестарт Udev.

service udev restart

Отключите и снова подключите устройство и попробуйте

ls -lah /dev/arduino1

Где arduino1строка, определенная serialв выше .conf.

Смотрите также: Риски ftdi_eeprom? - TX всегда высокий после перепрошивки

оборота ansi_lumen
источник
3

Я бы использовал скрипт для создания псевдонима, /dev/а также установил группу и права на него, udevкак и другие ответы.

Но если у меня не было , udevя бы трубку lsusbв grepили awk, как lsusb|grep -e "idProduct".

Во всяком случае, с udevправилами или с lsusbи grepдля идентификации USB устройств, использование idVendor, idProductи iSerialв Device descriptorчасти , lsusbчтобы сделать правильный idenification. Он idVendorговорит вам, что производитель idProductдолжен идентифицировать продукт от производителя, но иногда они используют один и тот же идентификатор продукта для более чем одного продукта. Наконец, при необходимости, iSerialдолжен быть уникальный идентификатор для каждого примера этого продукта.

Андерс
источник
3

В Ubuntu 16.04 (и, может быть, в предыдущих версиях или других дистрибутивах) вы можете сделать:

> ls /dev/serial/by-id

который отображает (на моей коробке, где подключен Arduino UNO):

usb-Arduino__www.arduino.cc__0043_A4139363931351318241-if00

Вы можете легко определить идентификатор устройства 0043 (UNO) здесь.

Этот файл на самом деле является ссылкой /dev/ttyACM0в моем окне.

jfpoilpret
источник
2

Вы всегда можете сделать какой-то идентификатор для печати через последовательный порт в void setup (). После того, как определенная плата будет подключена, она отправит этот идентификатор на ваш интерфейс USB (который вы слушаете с помощью какого-либо приложения-демона на вашем Linux-боксе). Получив идентификатор, вы можете сопоставить его с его путем 'Arduino1': '/ dev / ttyACM0', 'Arduino2': '/ dev / ttyACM1', 'Arduino3': '/dev/ttyACM2'...etc

Помните, что когда устройство по какой-то причине отключено, оно может изменить свой физический путь, поэтому вам, возможно, придется переназначить их все. Для этого случая может быть полезно написать отдельную функцию ex: get_id (), которую вы можете вызывать в любое время (не только при запуске).

cyberbrain
источник
1

Я мог бы испытать искушение определить какой-то другой способ, например, заставить сам эскиз реагировать на специальную команду идентификации, просто чтобы избежать странных способов идентификации устройств USB.

EternityForest
источник
0

обзор

  • Один из способов, как ansi_lumen упомянул в своем ответе состоит в том, чтобы перепрограммировать микросхему EEPROM ftdi, чтобы иметь уникальный серийный номер, который затем можно было бы определить по правилам UDEV.

    Но оказывается, что он не будет работать на дешевых китайских Arduinos, у которых вместо FTDI есть чип CH340G, у которого нет EEPROM для хранения уникального идентификатора ( CH340B должен работать ).

  • Этот ответ предлагает написать правило UDEV со специальным скриптом, который просит Arduino отправить свой уникальный идентификатор через серийный номер. Проблема в том, что вам нужно изменить эскиз Arduino, и в целом это довольно сложно.

Идентификация по порту

Поэтому я нашел самый простой способ - использовать правила UDEV и идентифицировать Arduinos по порту usb (devpath), поэтому подключение Arduino к одному и тому же порту (даже во вложенных концентраторах usb) создаст постоянное имя .

Настройка TLDR:

Модифицированная версия этого

  1. Найдите Arduino idVendor и idProduct:

lsusb

Вы получите что-то вроде этого:

...
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 124: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter
Bus 003 Device 123: ID 214b:7000  
Bus 003 Device 122: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter
Bus 003 Device 121: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter
Bus 003 Device 120: ID 1a40:0101 Terminus Technology Inc. Hub
...

Подключив / отключив Arduino, найдите, какой он (у меня 3 подключенных). Мы ищем его ID. В моем случае "... ID 1a86: 7523 QinHeng ...". Итак, idVendor = 1a86, idProduct = 7523

  1. Создайте новый файл правил UDEV:

sudo nano /etc/udev/rules.d/99-usb-serial.rules

  1. Измените значения idVendor и idProduct в соответствии с тем, что вы нашли в предыдущем шаге при копировании, вставьте их в файл правил, который мы создали:

SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", SYMLINK+="ttyUSB-arduino%s{/devpath}"

  1. Перезагрузить правила UDEV

sudo udevadm control --reload

  1. Переподключите Arduinos и теперь у него будет уникальное имя. Чтобы проверить это, наберите:

ls /dev/ttyUSB*


Который будет выводить:

/dev/ttyUSB1 /dev/ttyUSB3 /dev/ttyUSB-arduino2.1 /dev/ttyUSB-arduino2.4 /dev/ttyUSB2 /dev/ttyUSB4 /dev/ttyUSB-arduino2.2 /dev/ttyUSB-arduino3

Как вы можете видеть, мы все еще получаем / dev / ttyUSBx, как и раньше, который всегда меняется в зависимости от того, какой из них был подключен первым. Но теперь у нас также есть / dev / ttyUSB-arduino {port}, которые всегда одинаковы для одного и того же порта и только для Arduinos. Чтобы проанализировать, что означает «..arduino2.4»: 2 относится ко второму порту ноутбука, а 4 - к четвертому порту на USB-концентраторе.

Чтобы лучше увидеть это, наберите:

lsusb -t

Выход:

...
/:  Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 480M
    |__ Port 1: Dev 5, If 0, Class=Human Interface Device, Driver=usbhid, 12M
    |__ Port 1: Dev 5, If 1, Class=Human Interface Device, Driver=usbhid, 12M
    |__ Port 2: Dev 84, If 0, Class=Hub, Driver=hub/4p, 480M
        |__ Port 1: Dev 85, If 0, Class=Vendor Specific Class, Driver=ch341, 12M
        |__ Port 2: Dev 86, If 0, Class=Vendor Specific Class, Driver=ch341, 12M
        |__ Port 3: Dev 87, If 0, Class=Hub, Driver=hub/4p, 480M
        |__ Port 4: Dev 88, If 0, Class=Vendor Specific Class, Driver=ch341, 12M
    |__ Port 3: Dev 89, If 0, Class=Vendor Specific Class, Driver=ch341, 12M
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/2p, 480M
    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/6p, 480M
...

При подключении / отключении вы можете видеть, какие устройства и на каких портах

Гинтарас Греблюнас
источник