Visualizzare valori su una Bargraph a led colorati con un microcontrollore PIC
In questo articolo vediamo come controllare una Bargraph da 30 led con un microcontrollore PIC qualsiasi utilizzando soltanto 3 I/O.
L’esempio è illustrato on la FreedomII con su montato il buon vecchio PIC16F877A ma è piuttosto banale adattarlo ad un qualsiasi altro microcontrollore: bisogna soltanto saper leggere un ingresso analogico dato che il valore visualizzato sulla barra è proporzionale al valore letto da un ingresso A/D.
Possiamo utilizzare questo sistema anche come vu-meter, collegando opportunamente un ingresso AD al segnale da monitorare (attraverso partitori o amplificatori a seconda dei casi), come segnalazione di livello o altro.
In questo caso viene utilizzato il Trimmer presente di default sulla FreedomII, collegato alla porta RA1 (AN1) del 16F877A. In aggiunta la pressione del pulsante BT1, collegato su RB4, cambia la modalità di visualizzazione da barra a punto.
La Bargraph in questione è prodotta dalla Sparkfun. Io l’ho presa da Robot-Italy (qui). Sulla pagina di vendita è presente anche lo schema elettrico nonchè degli esempi per Arduino. Lo schema è abbastanza semplice: ci sono 4 shift register 74HC595 collegati in cascata che pilotano 3 bargraph da 10 led l’una. Ogni shift register è capace di gestire 8 bit, essendocene 4 “avanzano” due bit che la scheda della sparkfun riporta su due pin marcati come 31 e 32, utilizzabili per altre cose. E’ inoltre possibile collegare in cascata altre di queste schede.
La scheda 30 led Bargraph viene venduta in kit di montaggio, ad ogni modo è semplicissima da assemblare anche dai meno esperti: le resistenze di limitazione per i led fortunatamente non sono singole ma sono stati impiegati degli array per cui i componenti da montare non sono poi molti. L’unica piccola difficoltà è individuare il verso delle 3 bargraph: un angolo è leggermente rastremato ma è davvero difficile da visualizzare in un primo istante, c’è comunque un PDF fatto molto bene che illustra le fasi di montaggio per cui penso sia davvero impossibile sbagliare. Personalmente non ho usato zoccoli per i 4 integrati ma ho usato invece degli strip torniti per le barre di led perchè sono troppo esigente e tra un po’ sicuramente mi verrà la voglia di cambiare i colori! Scherzi a parte le 3 barre (verde/giallo/rosso) sono fatte molto bene e hanno dei colori vivaci.
La scheda sulla sinistra ha i pin di ingresso e sulla destra i pin di uscita per collegare altre schede in cascata.
Come funzionano gli shift register l’abbiamo già visto in alcuni articoli precedenti, e in particolare in questo viene illustrato proprio il funzionamento del 74HC595. Faccio quindi un semplice riassunto: abbiamo bisogno unicamente di 3 segnali. C’è un segnale dati (indicato come SIN sulla scheda, e che io ho indicato come DATA nel firmware del pic) sul quale vengono inviati i dati in cascata (1=led acceso, 0=led spento), una linea di clock grazie alla quale la transizione da livello alto a livello basso causa il trasferimento del bit presente sulla linea dati nello shift register e quindi lo scorrimento lungo di esso. Abbiamo infine una linea per il latch: la transizione del livello logico da alto a basso su tale linea consente il trasferimento dei dati dalla memoria interna ai latch di uscita e il dato viene quindi visualizzato sulle barre.
I collegamenti di queste 3 linee li ho fatti su RD0, RD1 e RD2:
#define DATA RD0 // RD0 da collegare a SIN della scheda #define LATCH RD1 // RD1 da collegare a LAT #define CLOCK RD2 // RD2 da collegare a CLK |
Il convertitore A/D fornisce un valore a 10 bit (valori da 0 a 1023) e noi dobbiamo riportarlo su 30 led, per cui basta fare una semplice proporzione come ci hanno insegnato alle elementari (questo sta a questo come quest’altro sta a quest’altro) che in codice si può tradurre come:
conversion=(valore*30)>>10; |
Dove valore è il risultato restituito dal convertitore A/D. Lo shift a destra di 10 a cosa serve? Qui per chi ha voglia di imparare c’è la risposta, ma tanto nelle note del sorgente è spiegato… Il valore conversion mi restituisce un numero da 0 a 29 (30 valori) che utilizzo per visualizzare il “punto” sulla barra da sinistra (0) verso destra (29). Ho deciso di trattare la barra come se fosse un numero intero a 32bit (nel quale i bit 31 e 32 non vengono sfruttati) e sposto quindi il “punto” lungo la barra con un semplice bitshift:
bar=1ul<<value; |
value è uguale a conversion, bar è il valore assunto dalla barra, che verrà poi serializzato e inviato agli shift register tramite l’apposita funzione. Dietro il valore 1 bisogna aggiungere ul che sta per unsigned long (intero senza segno a 32bit) per far capire al compilatore che deve trattare l’1 come un numero a 32bit, altrimenti lo considera come fosse un semplice intero a 8 bit, per cui lo spostamento dopo l’8bit produrrebbe risultati inaspettati.
La pressione del pulsante BT1 sulla Freedom, collegato a RB4, cambia la modalità di visualizzazione da barra a punto. In pratica in modalità barra vengono “riempiti” anche i led dal numero 0 fino a quello che identifica il valore. Il risultato è questo (il video l’ho realizzato con ORbit16™ ma il risultato è lo stesso):
Download
Il codice è scritto per Hitech-C Compiler 9.83, per cui fa uso dei nuovi nomi mnemonici. Se avete difficoltà a capire come viene inizializzato il modulo A/D leggete questa lezione.