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.
lsusb
Por 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/messages
O 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_eeprom
través deapt-get
o 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_id
eproduct_id
igualar. Personaliza las cadenas en elStrings
sección para obtener una identificación única para su dispositivo.Volcar el firmware actual de ftdi:
ftdi_eeprom --read-eprom
Este 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-eeprom
el 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.rules
y reiniciar udev.Desenchufe y vuelva a enchufar su dispositivo e intente
¿Dónde
arduino1
está la cadena definida debajoserial
en 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 conudev
las mismas respuestas.Pero si no tiene
udev
lo haría tuberíalsusb
engrep
oawk
, comolsusb|grep -e "idProduct"
.De todos modos, con
udev
reglas o conlsusb
ygrep
para identificar dispositivos USB, useidVendor
,idProduct
yiSerial
enDevice descriptor
partelsusb
para hacer la identificación adecuada. ElidVendor
le indica que elidProduct
fabricante 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,iSerial
debe 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/ttyACM0
mi 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
lsusb
Obtendrá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.rules
SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", SYMLINK+="ttyUSB-arduino%s{/devpath}"
sudo udevadm control --reload
ls /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-arduino3
Como 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