GPS-ino, tachimetro bussola altimetro GPS con Arduino
Prerogativa dei gadgets è quella di essere assolutamente inutili, e questo la rispetta in pieno. Il fatto è che
un pomeriggio, mentre trafficavo con qualche riparazione, il televisore in sottofondo ha attirato la mia attenzione con una scena nella quale il gruppo
di squinternati di turno misurava le prestazioni di un'auto con un "sofisticato tachimetro GPS". Nientemeno. Dunque, cosa può servire per realizzare un
simile aggeggio? Mentalmente ho cominciato l'inventario.. Ricevitore GPS: celo, con uscita RS232; controller: celo, magari l'arduino "Severino" utilizzato
nel precedente ArduLapse, con tanto di scheda display LCD. Manca il firmware, ma alla fine si
tratta di attingere i dati dalle stringhe NMEA provenienti dal GPS. Per quanto riguarda il display, pensando ad un utilizzo in auto, ho riconsiderato la
scelta del LCD per via delle implicazioni legate alla visibilità e alla retroilluminazione. Meglio in bel display a 7 segmenti LED verde che mi sono
ricordato di avere in qualche scatola. Ho dunque progettato una apposita "shield" per Arduino dotata del display a tre cifre, un paio di LED e pulsanti
(probabilmente la riciclerò per altri progetti) e i componenti necessari alla loro gestione.
Schema elettrico
Come accennato, sulla scheda trovano posto il display -nel mio caso in configurazione anodo comune- i transistor per
l'accensione delle tre cifre multiplexate, due pulsanti, due LED (si sa mai) e qualche resistenza:
I pin non utilizzati dell'Arduino sono collegati ad un connettore a passo 100 mils per eventuali espansioni,
sensori, eccetera. Il tutto è stato montato su una millefori secondo il layout sopra riportato.
Il ricevitore GPS utilizzato richiede una tensione di 5 volt e qualche decina di mA. Anzichè costruire un cavo
adattatore sdoppiato per alimentazione e segnali ho deciso di sfruttare uno dei pin inutilizzati della seriale a bordo del Severino e più precisamente
il pin 6 (DSR). Nell'uso normale il segnale DSR è in uscita dal dispositivo considerato, dunque la modifica apportata non crea problemi; in ogni caso ho
montato un jumper in una zona libera della piastra così da scollegare il segnale quando non necessario.
NMEA parsing
Lo standard di comunicazione universalmente adottato per i GPS è basato sul protocollo NMEA. Seppure
declinato in alcune varianti, sostanzialmente si compone di una serie di "sentenze", ossia stringhe di caratteri generate dai
ricevitori a ciclo continuo fino a formare un flusso di informazioni. Ogni sentenza è identificata da un prefisso alfanumerico "$GP"
che identifica l'inizio, seguito da tre lettere (es. RMC) che determina il tipo di informazioni contenute nei dati che seguono, ed infine
una serie di campi alfanumerici, separati da virgole, che costituiscono i dati utili. Ogni sentenza si chiude con un campo "checksum"
di controllo che serve a verificare la corretta ricezione dell'intero pacchetto. Per questo progetto ho scelto di visualizzare le informazioni relative
a velocità, direzione e altitudine, contenute nelle sentenze $GPGGA e $GPRMC di cui tutti i ricevitori con cui ho avuto a che fare dispongono.
Per estrapolare questi dati, anzichè arrabattarmi in algoritmi vari, ho deciso di apoggiarmi a una delle librerie già disponibili per Arduino: TinyGPS
ver.13. Da un lato questo semplifica di molto la vita (ed il listato dello sketch) dall'altro, raffrontato con il codice utilizzato ad esempio nel progetto
TNC KISS, utilizza molte più risorse in termini di RAM e di memoria programma del controller.
Da quello che ho potuto osservare scorrendo il sorgente della libreria ho notato che si fa un uso intensivo delle operazioni sulle stringhe di caratteri
e sui calcoli basati su variabili di tipo "long" e "float", che per un controller come l'ATMEGA8 sono dei macigni. L'intero sketch, allo stato attuale,
occupa circa l'80% della memoria di programma e la metà della RAM, rendendo comunque possibile aggiungere qualche altro orpello.
Lo sketch
Al momento il GPS-ino fornisce velocità, direzione e altitudine. Il pulsante SW1 consente di passare da una
visualizzazione a quella successiva; ad ogni pressione le scritte "SPE" (speed), "COU" (course) e "HEI" (height) indicano quale dato sta per essere
visualizzato. Il display dispone di sole tre cifre, quindi ho previsto un "auto-ranging" che funziona come segue:
-Nel modo velocità, sotto i 100 Km/h viene visualizzata una cifra decimale (es. 45.7) oltre i 100 il decimale viene perso e sono visualizzati i valori
interi;
-Nel modo altitudine, fino a 999 metri viene visualizzata la quota in metri, oltre i 1000 la visualizzazione è in Km (es. 1250 m slm => 1.25).
La risoluzione in questa condizione è dunque di 10 metri, poco male..
SW2, così come i LED, non sono utilizzati.
Per il collaudo "on the road" ho utilizzato un contenitore non proprio indicato, come si vede dalla foto.
L'obiettivo era quello di non provocare cortocircuiti e dare un minimo di protezione meccanica alle schede, dunque anche la scatola dei cotton fioc può
andare. Ho messo in auto il gps-ino per qualche giorno per valutarne il funzionamento. A parte qualche pecca, superata in un secondo momento, si è
comportato come previsto. L'aggancio dei satelliti nel caso di "cold start" avviene in un paio di minuti, mentre il "warm start" impiega una ventina
di secondi, trascorsi i quali il display indica la velocità. Nei primi minuti, quando il ricevitore ha agganciato il segnale di un numero limitato di
satelliti, anche da fermi la velocità è un po' ballerina e oscilla intorno a 1-2 Km/h; dopo qualche minuto
il dato diventa ben più affidabile e quando ci si ferma al semaforo l'indicazione scende subito a zero punto zero. La direzione (forse sarebbe più corretto
chiamarla gradi bussola, o forse ancora gradi prua) è indicata appunto in gradi: 0 se ci muoviamo verso nord, 90 a est 180 a sud e così via. E' curioso
notare come certi cambi di direzione che il nostro cervello ritiene ad angolo retto in realtà non lo siano, così come, dopo aver superato una "esse" si
pensa di continuare sulla direzione originaria ma...
Per quanto riguarda la elevazione (metri sul livello del mare) senza entrare nell'incubo dei vari map datum, geoidi e altre amenità posso affermare,
confrontando il display con alcuni riferimenti certi, che la precisione del gps-ino è nell'ordine di qualche decina di metri, tutto sommato accettabile.
Ho comunque notato che la lettura è più precisa se l'apparecchio viene lasciato fermo alcuni minuti, mentre in movimento la stabilità è minore.
Migliorie apportate
Seppure pienamente utilizzabile ho voluto migliorare un paio di aspetti del prototipo dopo qualche utilizzo.
Per primo mi sono occupato di un particolare comportamento conseguente all'accoppiata GPS + Severino. In pratica, applicando tensione il ricevitore
GPS inizia da subito a "sputare sentenze", ossia a mandare dati a raffica sulla seriale; a sua volta, nei primi secondi dall'accensione il controller
del Severino manda in esecuzione il bootloader che verifica se dalla seriale arrivano dati di un nuovo firmware da caricare nella memoria di programma.
Ovviamente dati ce ne sono in abbondanza, ma non coerenti con ciò che riconosce come comandi validi, ragione per cui il tutto va in stallo e il sistema
non parte. Perchè questo avvenga è necessario collegare il GPS solo dopo il boot, quando il display indica 00. Questa operazione è un po' scomoda, ragione
per cui ho cercato il modo di evitarla. Il Severino dispone di un jumper JP0 a due posizioni che abilita/disabilita la comunicazione rs232, applicando
Vcc o GND ad un piedino di controllo. Ho quindi pensato ad un circuito di ritardo che all'accensione forza a livello basso quel punto del circuito per
qualche secondo disabilitando la seriale, per poi portarlo a livello Vcc per le normali operazioni. Ho realizzato una piccola schedina con l'immortale
timer 555; sul connettore JP0 del Severino sono presenti tutti i segnali necessari, quindi il timer si collega semplicemente alla piastra con un SIP a 3
pin. Il LED a bordo della scheda evidenzia la condizione di "Attendere prego..", mentre il tempo di intervento è determinato da R1 e C1. Con i valori
indicati il ritardo è di una quindicina di secondi.
La seconda miglioria riguarda la sezione di alimentazione. In origine a bordo del Severino è montato un regolatore
lineare tipo LM7805 senza dissipatore termico. In questa configurazione l'assorbimento totale della shield display, del ricevitore GPS e della scheda
stessa arriva a un centinaio di mA; alimentando il tutto dalla presa accendisigari il 7805 dissipa quindi poco meno di un watt, sufficiente a scaldarlo
per bene. Non ho eseguito misurazioni, ma empiricamente ho stimato oltre i 50°C la temperatura raggiunta a regime dall'integrato. Siamo ampiamente entro
le specifiche, ma ho comunque voluto aggiungere un "plus" al progetto, montando uno stadio regolatore switching. Tempo fa ho acquistato in rete dieci
moduli step-down basati sul LM2596 a circa un euro l'uno, ideali per questo scopo. Ho quindi smontato il 7805 e saldato tre fili che collegano il modulo
switching (già regolato per 5 volt in uscita) alla piastra del Severino. Nella foto che segue le due schedine aggiuntive sono visibili nel lato superiore
della scatola.
La piedinatura della shield è comune ai vari Arduino Uno, Duemilanove, Diecimila.. Nelle
schede dotate di sola USB è necessario utilizzare un adattatore di livelli RS232/TTL o direttamente un GPS con comunicazione
a livello TTL. E' sempre possibile, invece della UART hardware interna al controller, utilizzare la libreria SoftwareSerial
e assegnare un pin i/o arbitrario alla ricezione dei dati NMEA, anche se in questo caso è da verificare che la gestione dei task
relativi alla ricezione seriale non interferisca troppo con il multiplexing del display creando fastidiosi "sfarfallamenti". Per
quanto riguarda il progetto GPS-ino, dopo le ultime verifiche di rito è arrivato il momento di...