Come assegnare alle periferiche USB sempre lo stesso nome

L’altro giorno mi sono trovato di fronte a un problema interessante.
Sul mio raspberry ho connesso due convertitori USB-RS485, uno per trasmettere i dati e l’altro per riceverli.
Va da sé che nei programmi è indispensabile identificarli correttamente: se invio i comandi al convertitore che invece è predisposto a riceverli (e viceversa) non funziona più niente.

Nel programma python scriverò una cosa del genere

portaTra = serial.Serial(“/dev/ttyUSB0”, baudrate=115200, timeout=10.0)

portaRic = serial.Serial(“/dev/ttyUSB1”, baudrate=115200, timeout=10.0)

dove ttyUSB0 e ttyUSB1 sono i due nomi dei due convertitori.
Il problema è che non sono sempre quelli. Delle volte si invertono, magari perché li connetti a porte USB diverse (e questo è comprensibile) ma mi è capitato che di invertissero facendo un riavvio del raspberry anche lasciano i convertitori nelle medesime porte USB.
Lasciare quindi i dispositivi nelle stesse porte non è una garanzia che i nomi rimangano gli stessi, raramente al riavvio si invertono.
E in generale non è una buona pratica fare affidamento sulla porta a cui sono connessi i dispositivi: devi sempre prevedere che ci sia un pirla (magari te stesso che te ne sei dimenticato) che scollega e ricollega i convertitori USB in modo sbagliato.

Serve qualcosa di robusto, un sistema per cui qualsiasi cosa accada, qualsiasi siano le porte in cui connetti i dispositivi USB gli dia sempre lo stesso nome univocamente, senza possibilità di errore.

Ho trovato questo trucchetto per ottenere questo risultato.

Innanzitutto dobbiamo trovare un modo per identificarli univocamente.
Per fare questo andiamo in /var/log/messages e scendiamo in fondo al log dove, in mezzo a mille altre cose, troviamo qualcosa del tipo:

usb 1-1.4: SerialNumber: AI22UK54
usb 1-1.4: FTDI USB Serial Device converter now attached to ttyUSB0
usb 1-1.5: SerialNumber: AI22UJ57
usb 1-1.5: FTDI USB Serial Device converter now attached to ttyUSB1

Usiamo il SerialNumber dei convertitori USB-RS485 come strumento per identificarli univocamente.
Facciamo questo perché essendo dei dispositivi identici si basano sullo stesso chip quindi l’idProduct e l’idVendor sono identici per entrambi (nel caso specifico idVendor=”0403″ e idProduct=”6001″).

Dopodiché dobbiamo dire al raspberry di assegnare un nome specifico al convertitore che ha numero seriale AI22UK54 e un altro nome a quello che ha numero seriale AI22UJ57.

Quindi andiamo in /etc/udev/rules.d e creiamo un file dal nome 99-usb-serial.rules dove scriviamo questa regola per il raspberry

SUBSYSTEM==”tty”, ATTRS{idVendor}==”0403″, ATTRS{idProduct}==”6001″, ATTRS{serial}==”AI22UK54″, SYMLINK+=”ttyUSB.tra”
SUBSYSTEM==”tty”, ATTRS{idVendor}==”0403″, ATTRS{idProduct}==”6001″, ATTRS{serial}==”AI22UJ57″, SYMLINK+=”ttyUSB.ric”

salviamo e riavviamo.

A questo punto nel programma potremo scrivere

portaTra = serial.Serial(“/dev/ttyUSB.tra”, baudrate=115200, timeout=10.0)

portaRic = serial.Serial(“/dev/ttyUSB.ric”, baudrate=115200, timeout=10.0)

Usiamo cioè ttyUSB.trattyUSB.ric al posto di ttyUSB0ttyUSB1 perché poi ci pensa il sistema da solo a collegare ttyUSB.trattyUSB0ttyUSB1 a seconda di come è stato caricato quel dispositivo a quel riavvio.
Io non mi devo più preoccupare se è ttyUSB0 o ttyUSB1, mi basta scrivere ttyUSB.tra.

Un trucchetto semplice semplice che può aumentare di molto l’affidabilità di un sistema che deve funzionare da solo in automatico senza l’intervento di un umano.

Fonte