Si tengo varios Arduinos conectados por USB a una computadora Linux, y aparecen como
- / tty / ACM0
- / tty / ACM1
- / tty / ACM2
¿Cómo puedo identificar qué Arduino es cuál sin conectarme a ellos mediante una conexión en serie ? ¿Hay un número de serie o una identificación única en el Arduino?
Gracias por tu tiempo.
Situación: Uno R3, Mega, Leonardo con / ttyACM [1,2,3]
Salida lsusb con dispositivos en el orden mencionado anteriormente:
... Bus 001 Dispositivo 011: ID 2341: 0043 Bus 001 Dispositivo 013: ID 2341: 8036 ... Bus 001 Dispositivo 014: ID 2341: 0042
lsusb -d vendor: dispositivo -vvv muestra para cada uno
Uno
Bus 001 Dispositivo 014: ID 2341: 0042
Descriptor de dispositivo:
bLongitud 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
Descriptor de configuración:
bLongitud 9
bDescriptorType 2
wTotalLength 62
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xc0
Autoalimentado
MaxPower 100mA
Descriptor de interfaz:
bLongitud 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 2 Communications
bInterfaceSubClass 2 Abstract (módem)
bInterfaceProtocol 1 Comandos AT (v.25ter)
iInterface 0
Encabezado de CDC:
bcdCDC 10.01
CDC ACM:
bmCapabilities 0x06
envía descanso
codificación de línea y estado serial
Unión de los CDC:
bMasterInterface 0
bSlaveInterface 1
Descriptor de punto final:
bLongitud 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 3
Tipo de transferencia interrupción
Tipo de sincronización Ninguno
Datos de tipo de uso
wMaxPacketSize 0x0008 1x 8 bytes
bIntervalo 255
Descriptor de interfaz:
bLongitud 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 10 CDC Data
bInterfaceSubClass 0 sin usar
bInterfaceProtocol 0
iInterface 0
Descriptor de punto final:
bLongitud 7
bDescriptorType 5
bEndpointAddress 0x04 EP 4 OUT
bmAttributes 2
Tipo de transferencia a granel
Tipo de sincronización Ninguno
Datos de tipo de uso
wMaxPacketSize 0x0040 1x 64 bytes
bIntervalo 1
Descriptor de punto final:
bLongitud 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 2
Tipo de transferencia a granel
Tipo de sincronización Ninguno
Datos de tipo de uso
wMaxPacketSize 0x0040 1x 64 bytes
bIntervalo 1
Estado del dispositivo: 0x0000
(Bus alimentado)
Leonardo
Bus 001 Dispositivo 013: ID 2341: 8036
Descriptor de dispositivo:
bLongitud 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 (definido en el nivel de interfaz)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x2341
idProduct 0x8036
bcdDevice 1.00
iManufacturer 1 Arduino LLC
iProduct 2 Arduino Leonardo
iSerial 0
bNumConfigurations 1
Descriptor de configuración:
bLongitud 9
bDescriptorType 2
wTotalLength 100
bNumInterfaces 3
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus alimentado)
MaxPower 500mA
Asociación de interfaz:
bLongitud 8
bDescriptorType 11
bFirstInterface 0
bInterfaceCount 2
bFunctionClass 2 Communications
bFunctionSubClass 2 Abstract (módem)
bFunctionProtocol 1 comandos AT (v.25ter)
iFunction 0
Descriptor de interfaz:
bLongitud 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 2 Communications
bInterfaceSubClass 2 Abstract (módem)
bInterfaceProtocol 0 Ninguno
iInterface 0
Encabezado de CDC:
bcdCDC 1.10
Gestión de llamadas de los CDC:
bmCapabilities 0x01
gestión de llamadas
bDataInterface 1
CDC ACM:
bmCapabilities 0x06
envía descanso
codificación de línea y estado serial
Unión de los CDC:
bMasterInterface 0
bSlaveInterface 1
Descriptor de punto final:
bLongitud 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Tipo de transferencia interrupción
Tipo de sincronización Ninguno
Datos de tipo de uso
wMaxPacketSize 0x0040 1x 64 bytes
bIntervalo 0
Descriptor de punto final:
bLongitud 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 2
Tipo de transferencia a granel
Tipo de sincronización Ninguno
Datos de tipo de uso
wMaxPacketSize 0x0040 1x 64 bytes
bIntervalo 0
Descriptor de interfaz:
bLongitud 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 0
bNumEndpoints 1
Dispositivo de interfaz humana bInterfaceClass 3
bInterfaceSubClass 0 Sin subclase
bInterfaceProtocol 0 Ninguno
iInterface 0
Descriptor de dispositivo HID:
bLongitud 9
bDescriptorType 33
bcdHID 1.01
bCountryCode 0 No compatible
bNumDescriptors 1
Informe bDescriptorType 34
wDescriptorLength 101
Descriptor de informe: (la longitud es 101)
Elemento (global): página de uso, datos = [0x01] 1
Controles de escritorio genéricos
Elemento (local): uso, datos = [0x02] 2
Ratón
Elemento (Principal): Colección, datos = [0x01] 1
Solicitud
Elemento (local): uso, datos = [0x01] 1
Puntero
Elemento (Principal): Colección, datos = [0x00] 0
Físico
Elemento (Global): ID de informe, datos = [0x01] 1
Elemento (global): página de uso, datos = [0x09] 9
Botones
Elemento (local): Uso mínimo, datos = [0x01] 1
Botón 1 (primario)
Elemento (local): uso máximo, datos = [0x03] 3
Botón 3 (terciario)
Elemento (Global): Mínimo lógico, datos = [0x00] 0
Elemento (Global): Máximo lógico, datos = [0x01] 1
Elemento (Global): Recuento de informes, datos = [0x03] 3
Elemento (Global): Tamaño del informe, datos = [0x01] 1
Elemento (Principal): Entrada, datos = [0x02] 2
Datos Variable Absoluta No_Wrap Lineal
Preferred_State No_Null_Position Non_Volatile Bitfield
Elemento (Global): Recuento de informes, datos = [0x01] 1
Elemento (Global): Tamaño del informe, datos = [0x05] 5
Elemento (Principal): Entrada, datos = [0x03] 3
Constante Variable Absoluta No_Wrap Lineal
Preferred_State No_Null_Position Non_Volatile Bitfield
Elemento (global): página de uso, datos = [0x01] 1
Controles de escritorio genéricos
Elemento (local): uso, datos = [0x30] 48
Dirección-X
Elemento (local): uso, datos = [0x31] 49
Dirección-Y
Elemento (local): uso, datos = [0x38] 56
Rueda
Elemento (Global): Mínimo lógico, datos = [0x81] 129
Elemento (Global): Máximo lógico, datos = [0x7f] 127
Elemento (Global): Tamaño del informe, datos = [0x08] 8
Elemento (Global): Recuento de informes, datos = [0x03] 3
Elemento (Principal): Entrada, datos = [0x06] 6
Datos Variable Relativo No_Envoltura Lineal
Preferred_State No_Null_Position Non_Volatile Bitfield
Elemento (Principal): Finalizar colección, datos = ninguno
Elemento (Principal): Finalizar colección, datos = ninguno
......
Descriptor de punto final:
bLongitud 7
bDescriptorType 5
bEndpointAddress 0x84 EP 4 IN
bmAttributes 3
Tipo de transferencia interrupción
Tipo de sincronización Ninguno
Datos de tipo de uso
wMaxPacketSize 0x0040 1x 64 bytes
bIntervalo 1
Estado del dispositivo: 0x0000
(Bus alimentado)
Y Mega256:
Bus 001 Dispositivo 014: ID 2341: 0042
Descriptor de dispositivo:
bLongitud 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
Descriptor de configuración:
bLongitud 9
bDescriptorType 2
wTotalLength 62
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xc0
Autoalimentado
MaxPower 100mA
Descriptor de interfaz:
bLongitud 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 2 Communications
bInterfaceSubClass 2 Abstract (módem)
bInterfaceProtocol 1 Comandos AT (v.25ter)
iInterface 0
Encabezado de CDC:
bcdCDC 10.01
CDC ACM:
bmCapabilities 0x06
envía descanso
codificación de línea y estado serial
Unión de los CDC:
bMasterInterface 0
bSlaveInterface 1
Descriptor de punto final:
bLongitud 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 3
Tipo de transferencia interrupción
Tipo de sincronización Ninguno
Datos de tipo de uso
wMaxPacketSize 0x0008 1x 8 bytes
bIntervalo 255
Descriptor de interfaz:
bLongitud 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 10 CDC Data
bInterfaceSubClass 0 sin usar
bInterfaceProtocol 0
iInterface 0
Descriptor de punto final:
bLongitud 7
bDescriptorType 5
bEndpointAddress 0x04 EP 4 OUT
bmAttributes 2
Tipo de transferencia a granel
Tipo de sincronización Ninguno
Datos de tipo de uso
wMaxPacketSize 0x0040 1x 64 bytes
bIntervalo 1
Descriptor de punto final:
bLongitud 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 2
Tipo de transferencia a granel
Tipo de sincronización Ninguno
Datos de tipo de uso
wMaxPacketSize 0x0040 1x 64 bytes
bIntervalo 1
Estado del dispositivo: 0x0000
(Bus alimentado)

lsusb -vvv¿dice?Respuestas:
Suponiendo que su distribución esté usando
udev:Es posible que necesite privilegios de root para ejecutar esto (sudo / su). Producirá una lista de información como esta:
Esto es para un Uno con firmware modificado en el atmega16u2 (usb a serial). Las líneas de interés son probablemente ID_MODEL_ID e ID_MODEL_FROM_DATABASE.
fuente
Puede agregar un alias para cada uno. Entonces sabes cuál es cuál. Aquí hay un buen tutorial sobre cómo configurar esto.
Aquí hay un fragmento que escribí basado en el tutorial. En el ejemplo a continuación, estoy usando un adaptador USB a serie FTDI RS232RL, que creo que es el que usa también el Arduino.
lsusbPor lo tanto, podemos leer este archivo y encontrar el USB correcto:
También puedes usar "usb"
Esto es encontrar todos los mensajes etiquetados con ftdi:
Junto a ftdi_sio, hay un número como 1-1.2. Este es el dispositivo USB
grep "usb 1-1.2" /var/log/messagesO puedes usar:
En este ejemplo, mi alias se llama 'lcdbox'
Guarde el archivo y escriba
control de sudo udevadm --reload-rules
Tipo
ls –l / dev / lcdbox
lrwxrwxrwx 1 root root 7 1 de enero de 1970 / dev / lcdbox -> ttyUSB0
fuente
¡Esto es bastante fácil! Debe personalizar el firmware de los chips ftdi y agregar una regla udev:
Primero, obtenga a
ftdi_eepromtravés deapt-geto desde las fuentes. Identifique su dispositivo a través de lsusb y obtenga la identificación:Preparar una configuración y asegúrese de que
vendor_ideproduct_idigualar. Personaliza las cadenas en elStringssección para obtener una identificación única para su dispositivo.Volcar el firmware actual de ftdi:
ftdi_eeprom --read-epromEste comando crea
${pwd}/eeprom.old, que contiene el firmware actual en el ftdi. Haga una copia de seguridad de este archivo antes de continuar , porque duranteflash-eepromel archivo se reescribe. Después de la copia de seguridad, muestre el ftdi:Ahora, crea una regla de udev, así
en
/etc/udev/rules.d/90-arduino-usb.rulesy reiniciar udev.Desenchufe y vuelva a enchufar su dispositivo e intente
¿Dónde
arduino1está la cadena definida debajoserialen lo anterior.conf?Ver también: ¿ Riesgos de ftdi_eeprom? - TX siempre alto después de parpadear
fuente
Habría usado un script para crear un alias
/dev/y también establecer un grupo y derechos conudevlas mismas respuestas.Pero si no tiene
udevlo haría tuberíalsusbengrepoawk, comolsusb|grep -e "idProduct".De todos modos, con
udevreglas o conlsusbygreppara identificar dispositivos USB, useidVendor,idProductyiSerialenDevice descriptorpartelsusbpara hacer la identificación adecuada. ElidVendorle indica que elidProductfabricante debe identificar el producto del fabricante, pero a veces usan la misma identificación de producto para más de un producto. Por último, si es necesario,iSerialdebe ser una identificación única para cada ejemplo de ese producto.fuente
En Ubuntu 16.04 (y tal vez versiones anteriores u otras distribuciones también), puede hacer:
que muestra (en mi caja donde está conectado un Arduino UNO):
Puede detectar fácilmente la ID de dispositivo 0043 (UNO) aquí.
Este archivo es en realidad un enlace a
/dev/ttyACM0mi caja.fuente
Siempre puede hacer algún tipo de impresión de identificación a través de serie en la configuración nula (). Después de que se conecte cierta placa, enviará esta identificación a su interfaz USB (que está escuchando con algún tipo de aplicación daemon en su caja de Linux). Una vez que reciba la identificación, puede asignarla a su ruta 'Arduino1': '/ dev / ttyACM0', 'Arduino2': '/ dev / ttyACM1', 'Arduino3': '/dev/ttyACM2'...etc
Tenga en cuenta que cuando el dispositivo se desconecta por alguna razón, puede cambiar su ruta física, por lo que es posible que tenga que reasignarlos todos. Para este caso, podría ser bueno escribir una función separada, por ejemplo: get_id (), a la que puede llamar en cualquier momento (no solo en el inicio).
fuente
Me sentiría muy tentado a identificar de alguna otra manera, como hacer que el boceto responda a un comando de identificación especial, solo para evitar las formas extrañas de USB de identificar dispositivos.
fuente
Visión general
Una forma como ansi_lumen mencionó en su respuesta es flashear la EEPROM del chip ftdi para tener un número de serie único que luego podría identificarse mediante las reglas UDEV.
Pero resulta que no funcionará en Arduinos chinos baratos que, en lugar de FTDI, tienen un chip CH340G que no tiene EEPROM para almacenar una identificación única ( CH340B debería funcionar ).
Identificando por puerto
Entonces, la forma más fácil que encontré fue usar reglas UDEV e identificar Arduinos por el puerto usb (devpath) para que conectar Arduino al mismo puerto (incluso en hubs usb anidados) cree un nombre persistente .
Configuración TLDR:
Versión modificada de esto
lsusbObtendrás algo como esto:
Al conectar / desconectar Arduino, encuentre cuál es (tengo 3 conectados). Estamos buscando su identificación. En mi caso "... ID 1a86: 7523 QinHeng ...". Entonces idVendor = 1a86, idProduct = 7523
sudo nano /etc/udev/rules.d/99-usb-serial.rulesSUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", SYMLINK+="ttyUSB-arduino%s{/devpath}"sudo udevadm control --reloadls /dev/ttyUSB*Lo que dará salida:
/dev/ttyUSB1 /dev/ttyUSB3 /dev/ttyUSB-arduino2.1 /dev/ttyUSB-arduino2.4 /dev/ttyUSB2 /dev/ttyUSB4 /dev/ttyUSB-arduino2.2 /dev/ttyUSB-arduino3Como puede ver, todavía tenemos / dev / ttyUSBx como antes, que siempre cambian dependiendo de cuál se conectó primero. Pero ahora también tenemos / dev / ttyUSB-arduino {port} que siempre son iguales para el mismo puerto y solo para Arduinos. Para analizar lo que significa "..arduino2.4": 2 se refiere al segundo puerto de la computadora portátil y 4 al cuarto puerto en el hub USB.
Para verlo mejor, escriba:
Salida:
Al conectar / desconectar puede ver qué dispositivos están en qué puertos
fuente