Allegria ! l’orologiaio matto è tornato !!

Il titolo è volutamente provocatorio perchè sarebbe dovuto essere:

I DISPLAY A MATRICE: TECNICHE HW E SW PER L’UTILIZZO

Questo in quanto ciò che mi accingo a descrivere sono i display a matrice 8×8 (o 7×5 o 8×5) cercando di approfondire i metodi sia hardware che software per il loro utilizzo. Per questo ho prodotto alcuni prototipi (rimasti tali allo stato dell’arte) di orologi digitali che utilizzano proprio queste matrici. Premetto che le caratteristiche HW sono pressochè identiche (cambia solo la piedinatura) sia ad ANODO COMUNE che a CATODO COMUNE.  Quindi prima di entrare specificatamente nell’ argomento qualche video per mostrare alcuni di questi prototipi.

NB: per visualizzare i video: fate click sul link: si aprirà una finestra di dialogo che vi chiederà se aprire o salvare il file. I video sono visibili con Windows Media Player o altro analogo per i file wmv.

Mini Orologio Binario

Questo video dimostra come una semplice matrice 8×8 può visualizzare un orologio “BINARIO”.  Se  mi fosse venuto in mente tempo fa al posto di quello già presentato in un altro mio articolo  !

L’orologio a cascata

In questo video i singoli valori dell’orologio vengono visualizzati punto per punto: la sequenza mostra la formazione dei valori partendo da sinistra con le decine di ore e poi a seguire fino ai minuti. Lo scandire dei secondi viene visualizzato da un led/pixel sul terzo display da sinistra.

L’orologio scorrevole

Caratteri grandi che compongono le ore, i minuti e i secondi a scorrimento da destra verso sinistra all’infinito. Dato il tempo che intercorre per la formazione del carattere, si perdono circa 2/3 secondi tra la visualizzazione completa e la successiva.

Orologio a parole

In questo ultimo video un orologio “a parole”. In questo caso non si utilizza un display a matrice ma un dispositivo particolare: il DL2416T. Si tratta di un display “intelligente” composto da 4 digit con più segmenti in grado di visualizzare numeri, lettere dell’alfabeto e alcuni caratteri speciali. Questo dispositivo, ormai obsoleto, è oggi disponibile in versioni aggiornate ma purtroppo piuttosto “caro”. Quelli in mio possesso derivano dalla cannibalizzazione di alcune stampanti ad aghi degli anni 80/90. Come potete vedere dal video, questo è l’unico prototipo finito (con pcb sia per il display che per la parte “main” con il micro Arduino_Nano e l’elettronica di controllo).

CARATTERISTICHE DEI DISPLAY A MATRICE

In Rete si trovano moltissime immagini e esempi sull’utilizzo delle suddette matrici: possono essere un aiuto per appronfondire il loro specifico uso. Tuttavia molti esempi sono superficiali e, a mio parere, non esaustive. Quindi ciò che descriverò è soltanto frutto di studi ed esperienze personali. Ogni eventuale riferimento  è puramente casuale.

Nella figura sottostante si può notare: il display 8×8, il modulo che alloggia sia il display che il suo controllore (MAX7219), il layout logico assegnato e gestito dagli sketch, e infine l’assegnazione dei pin della matrice sul modulo. L’ orientamento del display alloggiato sul modulo ha una sola posizione (8 pin a destra e 8 a sinistra) per cui se viene inserito al contrario ovviamente non si accenderà correttamente. Dalla quarta figura si può verificare l’assegnazione dei pin del display con quelli del controllore (MAX7219), Si può quindi dedurre quali sono i catodi (che chiamerò “DIGIT“) e quali sono gli anodi (che chiamerò “SEGMENTI“). Il display in esame è a CATODO COMUNE.

Il motivo per cui ho definito i catodi “DIGIT” e gli anodi “SEGMENTI” deriva dal come viene gestito sia dall’hardware che dal software il display e il relativo controllore. Questi display possono essere paragonati ai display a 7 segmenti + 1 definiti come “A”, “B”, “C”, “D”, “E”, “F”, “G”, “DP” (punto decimale o ottavo segmento). Ogni colonna di 8 led/pixel della matrice (vedere la terza figura) può rappresentare un display a 7+1 segmenti e quindi una matrice può essere paragonata ad una catena di 8 display a segmenti. Per accendere un singolo led/pixel è sufficiente applicare il pin “catodo” della colonna a massa e il pin “anodo” del singolo segmento a un valore logico “1” (+5V tramite R di caduta). E’ chiaro che per formare un carattere o un numero occorre accendere più led/pixel secondo un formato prestabilito nello stesso tempo (persistenza del’immagine per l’occhio): ovvero usare il multiplexing. Non ha senso connettere digit e segmenti (8+8 pin) alle uscite di un microcontrollore (con ovviamente resistori di caduta) e con inutili complicazioni a livello di programmazione.

Nei miei progetti ho sempre usato quello che ritengo il “principe” degli “shift register” in quanto con soli 3 pin riesce a pilotare una catena di 8 matrici connesse in cascata tra loro oppure 8 display a 7 segmenti. Con una limitazione (vedremo  poi che non lo è) : solo moduli a “CATODO COMUNE”. Questo chip (costi irrisori se un modulo con tanto di display vale da 1,5 a 5 euro) è il MAX7219. Queste le caratteristiche principali:

  • 3 PIN per il pilotaggio (LOAD/CLOCK/DATA_IN).
  • Multiplexing integrato.
  • Luminosità regolabile da programma.
  • Pin DATA_OUT per la connessione di un altro display.
  • Gestisce indifferentemente sia i display a segmento che le matrici.
  • 7 registri per i comandi operativi e 8 per i digit.
  • Limitazione della luminosità anche dall’esterno con trimmer.

COME UTILIZZARE E PROGRAMMARE IL CHIP MAX7219

Uso ormai questo chip per tutti i progetti che implicano la gestione di display sia a matrice che a segmenti oppure per array di led anche RGB. A proposito dei led RGB prossimamente pubblicherò la “STELLA DI NATALE” anche se non è la stagione !. Approfondiamo allora con i pin del chip e i vari registri:

DG0/DG7 pilotano i catodi dei display, SEG_A/SEG_DP pilotano gli anodi dei display. Per i display a matrice DG0/DG7 sono riferiti alle colonne mentre SEG_A/DP sono riferiti ai singoli led/pixex della colonna. L’ attribuzione Segmento/Led ed il relativo valore binario deve essere configurato nel registro “DATA” tenendo presente che il bit “DP” vale 128 (0x80). Il pin DIN è relativo all’input dati , il pin Load/Cs seleziona il chip, il pin CLK fornisce il clock e per ultimo il pin DOUT è quello che permette la connessione in cascata di un altro chip per un massimo di 8. Ultimo il pin “ISET “per regolare il valore della luminosità connettendo una R da 10K (o un trimmer) al polo positivo.

Vediamo adesso i registri:

Uso e significato dei singoli registri:

  • Registro 0: Posto a “0x00” serve soltanto nelle catene di display. (0vvero nessuna operazione per lo specifico display).
  • Registri 1/8: Sono i registri che indirizzano i singoli segmenti per l’accensione dei singoli segmenti (vedi formato DATA REGISTER).
  • Registro 9: Decode_Mode: serve al chip per sapere se viene usato il codice BCD o nessuno.
  • Registro 10: Variazione della luminosità. Valore da 0 a 15. Con il valore zero non si ottiene lo spegnimento del display bensì la sua luminosità minima. Si possono effettuare effetti luminosi portando questo registro da 0 a 15 in modo progressivo e cadenzato.
  • Registro 11: Scan limit: occorre indicare effettivamente quanti digit devono essere scansionati: una tabella sul datasheet indica i valori da assegnare.
  • Registro 12: Modo operativo (ShutDown). Alternando il valore di questo registro (da 0x00 a 0x01) si ottiene l’accensione o lo spegnimento del display (senza perdere l’eventuale valore presente). Può essere utile per creare l’effetto lampeggio alternando i due valori in modo cadenzato.
  • Registro 13/14: Non presenti.
  • Registro 15: Test del dispositivo: si ottiene l’accensione di tutti i led connessi.

In sostanza per eseguire uno specifico comando occorrerà inviare al chip 2 byte: l’indirizzo del registro e il valore che deve assumere in funzione del comando stesso: ad esempio per avviare in modo normale occorre inviare la sequenza: “0c00“.

 

IL SOFTWARE DI GESTIONE

Eccoci arrivati alla parte più interessante: come gestire questi display. In rete, ovviamente, si possono trovare numerosi esempi e librerie e agli inizi avevo scaricato un paio di queste librerie: LEDCONTROL e LEDCONTROLMS e usate per le prime prove . Sono valide ma pesonalmente non mi soddisfano per cui ho sviluppato a mio uso e consumo una “libreria sui generis” in grado di gestire sia i display CATODO che ANODO domune. L’ho definita “sui generis” in quanto non è stata scritta secondo i canoni ma è in realtà un file (.ino) che racchiude tutte le funzioni necessarie ed implementate sia per le matrici che per i 7 segmenti. E’ sufficiente includere questo file nello sketch per effettuare poi i richiami. (Mi riservo di convertire questo file in una libreria vera e propria). Poichè l’incipit di questo articolo riguarda le matrici vediamo come possono essere gestite.

Per prima cosa occorre definire quante matrici devono essere trattate: una o più. Se per una singola matrice non ci sono particolari problemi, quando si tratta di connetterne più di una occorre adottare o un pcb oppure effettuare collegamenti volanti. Vediamo questa figura:

La prima matrice è connessa al micro con i classici pin LOAD/DIN/CLOCK: quindi se è l’unica non occorre altro. Dalla seconda in poi le connessioni LOAD/CLK sono connesse tra loro ma la seconda matrice (o la terza e così via) il suo DIN è connesso al DOUT della matrice precedente. E’ compito del software indirizzare correttamente le matrici. (Ricordate il registro “zero” ?) . L’uso di questo modulino facilita le connessioni:

Gli ingressi sono quelli visti prima e i pin in uscita sono VCC, GND, LOAD, CLK, DOUT. Per il prototipo dell’orologio scorrevole o in cascata, ho usato 4 display alloggiati in questo pcb:

 

A sinistra i pin di ingresso principale, in fondo a destra i pin di uscita per connettere eventuali altre matrici. Lo spazio di ciascun modulo è stato delimitato dai rettangoli in rosso. Non mancano i pin VCC e GND.

Fatta questa premessa facciamo  i primi passi per la gestione. Le prime operazioni da effettuare nel “setup” di un qualsiasi sketch sono: (D’ora in poi per “DEVICE” identifico il chip e per “DISPLAY” i singoli digit o colonne della matrice). Tutte le seguenti operazioni devono essere eseguite per ogni “device” presente. Si tenga presente che all’accensione del sistema, nella maggior parte dei casi, si avrà un autotest del chip che accenderà tutti i led per cui può essere buona norma effettuare queste operazioni prima di tutte le altre altrimenti si avrà la persistenza dei led accesi. 

  • Assegnazione dei pin del chip al micro come output.
  • Effettuare lo Shutdown per inizializzare il chip.
  • Impostare la luminosità.
  • Impostare il modo di codifica.
  • Impostare il modo test.
  • Impostare lo “Scan Limit”.

Tutte queste operazioni vengono gestite tramite una funzione nella mia libreria definita come “Led_MX_Init” che imposta i pin, effettua l’inizializzazione e assegna il metodo “CATODO” O “ANODO” comune. Per comodità per il debug di questa libreria ho inserito anche (tramite flag nella init) la possibilità di visualizzare via seriale l’emissione dei valori da inviare ai registri. Per lo sviluppo della libreria ho implementato uno sketch che, via seriale, imposta un dialogo attraverso un menù che permette l’esecuzione di tutte le funzioni della libreria sia per le matrici che per i display 7 segmenti.

Avevo specificato che il chip può gestire soltanto i display a CATODO COMUNE: vero fino ad un certo punto perchè si possono usare anche quelli a ANODO COMUNE ma con i seguenti accorgimenti:

  • A livello HW: invertire i segnali DG0/DG7 interponendo un HEX INVERTER (74LS04). In questo modo agli ANODI arriva il corretto valore logico.
  • A livello SW: attivare il flag “ACMODE” nella funzione INIT della libreria. In presenza di questa attivazione le funzioni che gestiscono i led/pixel invertono il valore passato tramite l’ apposita funzione (Led_Value = ~ Led_Value;).
  • Allo stato dell’ arte la libreria utilizza questa funzione solo per i display 7 segmenti.

Vediamo adesso specificatamente per ciascuno dei prototipi orologio descritti all’inizio i metodi e i trucchi utilizzati per lo sviluppo degli stessi. Poichè si tratta di orologi è chiaro che occorre un RTC da cui leggere orario e data. Non ci sono specifiche particolari: si possono usare i DS1307 o Ds3231 oppure il PCF8583 (modello vetusto). Le uniche differenze sono la lettura dei registri e il metodo di decodifica. Per inciso non ho usato nessuna libreria per la gestione di questi RTC: accedo direttamente ai registri con le funzioni della libreria “wire“.

L’orologio binario: Questo è il più semplice di tutti gli altri. Lo sketch gestice un solo device (matrice 8×8) e dopo aver inizializzato il device e controllato il corretto funzionamento dell’RTC, esegue un ciclo nella funzione “loop” leggendo dai registri dell’RTC i valori dell’ora, minuti,secondi,giorno, mese. Poichè questi valori sono in formato “BCD” (le ore 12 sono in binario 0001 0010) non è necessaria alcuna decodifica per la loro visualizzazione. Facciamo un passo indietro: ho detto che la matrice può essere vista come un insieme di 8 display in cui ogni colonna rappresenta gli 8 segmenti (7+1) la cui codifica viene assegnata nel registro 1 per la colonna 1, 2 per la colonna 2 (e così via per le altre colonne) rispettando la codifica imposta dal chip (vedi figura “register data“). Allora il trucco è: ad ogni colonna scelta viene caricato il valore e allora le “famose ore 12” vengono così assegnate:

E così via per tutte le altre colonne. E la mascherina copre i bit la cui visualizzazione non è necessaria. Si tratta allora di comandare il chip colonna per colonna (dalla 1 alla 8 ma nel caso specifico  solo la 1, 2, 4, 5, e 7) e a questo provvede la funzione della libreria “LEDMTX_Setcolumn” a cui fornire il numero del device, il numero della colonna e il suo valore.

L’orologio scorrevole: Questo è più complesso del precedente ma non complicato e si tratta soltanto di ragionare sull’ algoritmo che determina lo scorrimento dei valori. Si inserisce in questo contesto un altro file (Led_Tabel.ino) che rappresenta sotto forma di array, quali sono le configurazioni binarie che devono assumere le singole colonne per la rappresentazione di un carattere numerico (da zero a nove)  sia per le matrici che per i display a 7 segmenti. Ora se per questi display la configurazione è determinata ed univoca,  per le matrici avendo a disposizione una griglia di 8×8 led/pixel diventa libera scelta dello sviluppatore configurare i vari numeri come più aggrada.

Ecco un esempio: per i display a segmenti il numero zero ha la seguente configurazione: 0111 1110. L’eventuale punto decimale (Segmento “DP“) può essere inserito portando a “1” il bit 8 oppure abilitando il flag nella apposita funzione. Quindi un byte per ogni numero e la funzione che effettua il display punta l’array in funzione del numero. (lo zero punta il primo byte dell’array, l’uno il secondo e così via).

Diverso è il sistema per le matrici: infatti per lo stesso numero occorrono ben 8 configurazioni e cioè un byte per ogni colonna. Lo stesso numero zero è così definito: “0,60,98,82,74,70,60,0“. I valori sono espressi in decimale e la configurazione è una scelta personale. Ne deriva che la funzione che visualizza il numero deve puntare al primo byte di ciascuna serie * 8 (“0” * “8” = “0” e punta al primo byte; “1” * “8” = 8 e punta al primo byte che configura il numero uno).  Poi colonna/colonna effettua la visualizzazione. La figura sottostante è un esempio di come possono essere composti i caratteri nella griglia 8×8.

Fatte queste premesse vediamo quale è l’algoritmo da me escogitato, per visualizzare i valori di un orologio facendoli scorrere da destra  a sinistra colonna per colonna. Lo scorrimento avviene su 4 device per un totale di 4*8 = 32 colonne: si crea quindi un array di 32 colonne. Tralascio la parte iniziale del setup (RTC, init del 7219 ecc) e quindi nel ciclo “loop” si effettua:

  • Lettura dei registri RTC
  • Decodifica dei valori delle ore, dei minuti e dei secondi per ottenere i singoli valori delle decine e delle unità. Questi valori servono per puntare nella tabella dei caratteri l’inizio dei singoli gruppi di 8 byte.
  • Cominciando dal valore delle decine di ore una routine estrae byte per byte la configurazione relativa dalla tabella e inserisce in posizione 32 dell’array il valore estratto uno alla volta. Inizia a questo punto la scansione dell’array che partendo dalla posizione “zero” visualizza il contenuto sulla prima colonna del primo device di sinistra e prosegue per 32 posizioni (i device sono 4 connessi in serie). Terminata questa scansione si shifta verso sinistra di una posizione tutto l’array e si ricomincia il ciclo con il successivo byte della configurazione. Quando è terminato il ciclo degli 8 byte si prosegue con le unità delle ore fino all’ unità dei secondi con lo stesso sistema. Si ottiene così l’effetto scorrimento. Ma tra una lettura e l’altra dell’ RTC e la sua completa visualizzazione si perdono  2/3 secondi per ciclo.

A questo punto entra in gioco un aspetto ancora non considerato nella gestione dei display. Come ho detto i  device sono 4 connessi in serie. Allora per indirizzare correttamente l’intero device (dal primo all’ultimo) sapendo che ogni comando consta di 2 byte (indirizzo/valore) occorre inviare un set di byte pari al numero del device su cui indirizzare i valori e i comandi:

Ovvero se il device è il quarto la sequenza è la seguente: “0000 0000 0000 xxxx. (Se il device fosse il primo la sequenza sarebbe: “xxxx“)

Dove: “0000” è il codice di NULL OPERATION, “xxxx” è il comando che deve essere inviato al quarto device (primo di destra). Ma la serializzazione deve partire dal quarto gruppo di byte (in pratica l’ultimo). Il chip riceve i primi 4 byte ma siccome in ciclo riceve anche i successivi a zero, fa scorrere i vari byte da un device all’altro. A tutto questo provvede una funzione specifica leggendo da una tabella (predisposta per 8 device)  i 4 valori partendo ovviamente dall’ultimo. E’ però la stessa funzione che stabilisce in base al numero del device quanti byte inviare.

Scusate ma è più facile a farsi che a dirsi. Spero di essere stato chiaro ma ATTENZIONE tutto ciò è relativo alla posizione del primo device a cui viene assegnato il numero 1.

L’orologio a cascata: Eccoci al più complesso, dal punto di vista dell’implementazione, di quelli persentati fino ad ora. Confesso che ho avuto qualche problema nel costruire l’algoritmo giusto per ottenere l’effetto che avete visto nel filmato. Tralascio anche in questa sede le operazioni standard che vanno eseguite nel “setup” per passare direttamente al metodo trovato. Allora nel ciclo “loop” si parte leggendo i valori dell’RTC, la loro conversione in decine di ore e minuti, unità di ore e minuti. I secondi vengono visualizzati facendo lampeggiare nel terzo device da sinistra, il led “DP” della prima colonna in base al valore del bit “1” dei secondi. Dal filmato si vede come inizialmente tutte le matrici vengono impostate con i valori, ma, ogni matrice cambia soltanto se il valore che deve visualizzare cambia rispetto al precedente. Se ogni valore letto dall’rtc (decine di ore o minuti, unità di ore o minuti) cambia, allora si attiva l’aggiornamento del display relativo. Per cui ogni 60 secondi circa (“circa” perchè la visualizzazione completa di una matrice occupa un pò di tempo) si aggiornano i minuti o le ore eccetera. Per ottenere l’effetto “cascata” dei singoli led di ogni colonna occorre prelevare dalla tabella (ne sono state prodotte tre per cui si può cambiare l’origine dei dati) il singolo byte (dal primo all’ottavo)  e si inizia facendo lampeggiare il primo led (bit 1) per 15 ms, poi si prosegue con il secondo ma facendo in modo che detto led precedente rimanga acceso (secondo la configurazione del carattere). Il byte a zero viene saltato. Il ciclo si ripete fino al completamento degli otto byte. Terminato questo ciclo si passa al carattere successivo fino al completamento. I 15 ms di ritardo tra un lampeggio e l’altro sono un compromesso tra velocità di esecuzione ed effetto voluto. Chiaramente il lampeggio dei secondi potrà non essere preciso specie se cambiano nello stesso tempo l’ora e i minuti.(da 23.59 a 00.00).

Non è facilissimo descrivere questo meccanismo, io stesso pur dopo averlo prodotto e modificato aggiungendo parametri variabili, faccio fatica a ricomprenderlo (!!!). Se non si è alle prime armi in fatto di programmazione, le routine sono sufficientemente commentate per essere comprese.

L’orologio parlante: Ed ecco l’ ultimo (sperando nel frattempo di non averVi annoiato). Ho voluto inserire questo anche per poter effettuare un confronto tra i diversi moduli display: in questo caso, tirato fuori dal cassetto delle cose vecchie ma ancora perfettamente funzionanti, si tratta del DL2416T un display particolare oggi sostituito dal DLR2416. Putroppo questi ultimi costano cari.

La differenza tra i due modelli possiamo vederla con questa figura:

Il primo è formato da 4 display a segmenti (14 se non ho contato male) mentre il secondo è a matrice 7×5. Le caratteristiche di questi display, compatibili sia come pin che funzioni, possono essere così riassunte: 

  • 4 digit indirizzabili singolarmente (“00”, “01”, “10”, “11”).
  • Device singolarmente indirizzabile (due pin di selezione)
  • Cancellabile singolarmente.
  • Set di caratteri speciali, alfanumerici e numerici.
  • Gestione automatica del multiplexing.
  • Alimentazione da 5 a 6V max.
  • Gestione del cursore
  • Altre caratteristiche nel datasheet di ciascuno.

Nella figura sottostante valida per i due modelli, i pin di connessione:

Verifichiamo: 2 pin per la selezione (CE1/2), 2 pin per l gestione del cursore (CUS,CUE), due pin per la selezione del digit (A0/A1), pin CLR per la cancellazione, pin BL per lo spegnimento senza perdita dei valori (utile per il blincaggio), 7 pin (D0/D6) per i DATA INPUT, infine il pin WE per la scrittura del valore. Una transizione HIGH-LOW-HIGH abilita la scrittura su quanto impostato. Valore ottimale sperimentato: 5us.

Data allora la complessità di connessione per due display (come nel prototipo), ho dovuto produrre un pcb come questo:

Non ho disegnato un circuito in quanto detto pcb serve soltanto all’alloggiamento dei due display connettendo in parallelo i pin D0/D6 e portando per la connessione al “main” i pin A0/A1, WE, CL1, CL2, BL1, BL2. I pin CUS e CUE in questo contesto non sono usati e sono posti ai valori di default (livello logico “0” e “1”). Una nota particolare riguarda i pin CL1/2 e BL1/2: secondo il datasheet la cancellazione di un display o il suo abblencamento sono indipendenti dalla selezione del display stesso: non possono essere (ma è una scelta) connessi in parallelo se si vuole cancellare o spegnere il singolo display. Cosa che ho previsto successivamente nel software. Di seguito invece il pcb relativo alla main board per il micro Arduino_Nano e i due 74Hc595.

 

Passiamo allora al cuore del prototipo.

Risulta chiaro che dato il numero delle connessioni (6 per i DATA INPUT) e 9 per i comandi, si esaurirebbero tutti i pin di ARDUINO (Uno o Nano che sia tralasciando i Mega ecc), per cui occorre un approccio diverso come si nota in questo schema elettrico:

Nello schema possiamo notare 2 74HC595 (shift register) dove nel primo sono definiti nelle uscite i pin D0/D6 relativi al DATA INPUT dei display mentre nel secondo sono definiti i pin dei comandi:  Ao/A1, CL1/2,BL1/2, CE1/2. I due chip sono connessi in cascata e secondo le regole degli shift register (che ricevono dati in seriali per ritrasmetterli in parallelo). Segnale QH  che si connette al DataIn del secondo.

Lo schema è relativo alla prima versione in quanto non è strettamente necessario separare i segnali OE, LE, CLK  perchè quello che serve singolarmente è il segnale OE che comanda l’uscita QO/Q7 (altrimenti sono in alta impedenza). E’ comunque una mia scelta la separazione dei segnali. Il segnale MR (master reset) serve a resettare il chip. I pin dei comandi sono connessi ai pin di Arduino;  il segnale “WE” è indipendente dal resto ed è attribuito ad un altro pin del micro.

Mentre per i chip 7219 si possono definire “intelligenti” perchè oltre alla funzione di shift register, abbisognano di comandi per l’attivazione delle funzioni, i 74hc595 sono “stupidi” perchè si limitano semplicemente a ricevere i bit seriali e se questi sono > 8 passano i successivi bit al successivo chip e così via. Sfruttando questo sistema l’algoritmo per comandare i display singolarmente può consistere nel:

  • Inviare ad un chip gli 8 bit relativi alla configurazione del carattere (8 bit sempre zero).
  • Inviare al successivo chip la configurazione dei bit di comando per selezionare il display e il suo digit; operazioni, queste, effettuate in sequenza.
  • Stabilizzare i segnali abilitando l’ OE dei due chip.
  • Attivare il segnale “WE” per l’effettiva scrittura sui display.

E’ chiaro che dovendo scrivere su 8 digit (2 display per 4 digit) le sigole lettere che compongono il testo completo (come avrete visto dal filmato) occorre stabilire la sequenza precisa dei comandi e del carattere da inviare . A tale proposito ho costruito la seguente tabella.

Come si legge questa tabella ?. Esempio: si vuole caricare il display “1” digit “0” con un carattere: allora si invia al primo chip il valore del carattere e al secondo chip il valore decimale “62“. La disposizione bit uscita (Q0/Q7) corrisponde ai segnali A1/A0, BL2, CL2, CE2, BL1, CL1, CE1 i quali sono a livello logico “1” (non operativi) o livello logico “0” operativi. Non ingannino i numeri espressi nella tabella in quanto mi  sono serviti per calcolare correttamente il valore quando sono a zero o uno. Altra cosa da tener presente è che in funzione di come sono stati connessi i chip ai segnali e quindi ai display, non è detto che il primo chip debba essere necessariamente quello per i dati o quello per i segnali.

Ancora un pò di pazienza: completiamo anche questo prototipo con il suo software. Come avrete capito anche in questo caso si tratta di gestire un orologio. Lo sketch non è complesso ma si può descrivere brevemente come segue:

  • Solita attivazione dell’ RTC con i soliti controlli di presenza ed efficienza per cui in mancanza il sistema non parte.
  • Configurazione dei pin connessi ai chip 74hc595.
  • Nel ciclo “loop” lettura dei valori RTC, trascodifica degli stessi e preparazione di una stringa composta dalle parole “SONO LE ORE ” dei valori dell’ora (decine e unità) intervallate da un punto, poi “DEL ” valore del giorno, trascodifica del mese e trascodifica del settimana. Per cui alla fine la stringa conterrà:
  • SONO LE ORE xx.xx DEL xx MAGGIO VENERDI —-> esempio. Gli spazi tra un parola e l’altra sono ottenuti con il carattere “00” binario che non produce nulla di visibile.
  • Dopo aver costruito la stringa, in base alla sua effettiva lunghezza si inserisce in un array d 8 byte in posizione 8, il primo carattere della stringa.
  • Si esegue un loop di 8 cicli per inviare i valori dell’array agli 8 digit dei display (set di comandi specifici per display e digit e data_value).
  • Si effettua lo shift dell’array di 8 byte da destra verso sinistra.
  • Si ripete il ciclo.

Si ottiene in questo modo l’effetto scorrimento la cui velocità programmata di 250ms può essere ritenuta ottimale per la visione.

 

CONCLUSIONE:

Riconosco che questo articolo è piuttosto lungo e probabilmente ho descritto cose ovvie  e risapute. Ma dal mio punto di vista modi vedere e scelte di implementazione, possono sempre essere una buona fonte di informazioni sopratutto per chi è alle prime armi o semplicemente hobbista come il sottoscritto.

Se poi ho scritto qualche imprecisione, non vogliatemene.

Grazie per l’attenzione.

GVSOFT MAGGIO 2018

PS: se siete interessati agli sketch e alla documentazione relativa scrivete a gvsoft75@hotmail.com.

 

 

 

 

VOTO
2 commenti
  1. theremino dice:

    Ho avuto le traveggole o in uno dei precedenti orologi matti c’era la spiegazione di come decodificare il segnale DCF77?
    Ho cercato l’articolo ma non lo trovo più.

    Approvazioni

Lascia un Commento

Vuoi partecipare alla discussione?
Fornisci il tuo contributo!

Lascia un commento