Un filo per un orologio

UN FILO PER UN OROLOGIO

Eccomi dopo una discreta assenza, a riproporvi l’ennesimo orologio digitale: ma ormai lo sanno tutti…la mia è una mania… o forse non so fare altro.

Come è nato quest’ultimo orologio ?… ancora nel mese di marzo girovando nel web in cerca di qualche dispositivo da provare e sperimentare ho trovato sul sito di Futura_Elettronica un led particolare: somigliante in tutto e per tutto ad un led RGB (quattro pin R,G,B,anodo/catodo) ma non era un led RGB. Pur avendo i 4 canonici piedini è in realtà un led WS212. Ecco come si presenta:

I piedini sono sempre 4 ma con definizioni diverse: ovvero DATA_IN, VCC,GND,DATA_OUT. Una tacchetta su un lato del led identifica il pin DATA_OUT. Alimentazione 5V. Formato del led: 5mm.

La curiosità uccide il gatto (famoso detto….) e così ho effettuato un primo ordine di 20 led per sperimentare e provare il funzionamento. Ho detto che sono led WS2812: ovvero utilizzano un protocollo specifico di tipo seriale gestito dalle librerie ADAFRUIT_NEOPIXEL.  Non è facile descrivere questo protocollo: praticamente una sequenza di 24 bit (8 per ogni colore) inviata serialmente accende il led con il colore definito per il led R, per il G e per il led B come da questa immagine (fonte ws2812.pdf).

Ovviamente ci sono delle tempistiche da rispettare ma non mi sono preoccupato più di tanto in quanto tutto il lavoro di gestione è affidato alla libreria. La particolarità di questi led è data dal tipo di connessione: ogni led viene connesso in cascata con il precedente formando quindi un catena praticamente senza limiti specifici: in effetti per realizzare questo orologio ho utilizzato ben 112 led.

Ecco allora in anteprima il risultato finale:

Abbiate pietà: sono una vera e propria frana nel bricolage e stavolta  mi sono anche superato: non è stato facile e solo in questi giorni ho praticamente finito i test.

 

LA REALIZZAZIONE DEFINITIVA:

Prima di partire in quarta ho effettuato uno studio di fattibilità (oggi è di moda) per decidere come connettere questi led, quale RTC usare, come aggiornare i valori dell’orario, come assegnare i colori e quale luminosità può essere accettabile per la visibilità e sopratutto come alimentare il tutto considerando la presenza di ben 112 led.  Questo problema dell’alimentazione e dell’assorbimento totale mi è costato molto tempo: non volevo correre il rischio di trovarmi senza un alimentatore adeguato: da fonti web ognuno di questi led dovrebbe assorbire ben 20ma per ogni colore. Quindi per un led al colore bianco occorre accendere i tre led con un assorbimento totale di 60ma. Ma questo poi si rileva un falso problema in quanto mai in questo orologio saranno accesi tutti i 112 led. Ma per evitare appunto inconvenienti ho preparato alcuni pcb con una serie di led connessi serialmente.

Secondo alcune prove effettuate con un normale tester sulla portata 200ma si sono rilevate le seguenti misure:  (Valore della luminosità  = 25 e secondo funzioni della libreria è un valore basso).

Catena con un solo led: Led spento: 07,7ma; Acceso rosso: 08,6ma; idem verde e blu; bianco 10,3ma; purple: 09,4;  giallo: 09,4.

Catena con 2 led: Spenti: 15,3; Acceso rosso 1: 16,1ma; idem verde e blu; bianco 17,8ma; purple/giallo 16,9ma; Acceso rosso 1+2: 16,9ma: idem con verde e blu. Bianco 20,3ma; purple/giallo 18,6.

Catena con 3 led: Spenti: 15,7; Acceso rosso 1: 16,6; verde, blu idem; Acceso rosso 1+2: 17,4; verde, blu idem; bianco 20,8; purple/giallo 19,1ma.Acceso rosso 1+2+3: 18,4; verde e blu idem; bianco 23,6ma; purple/ giallo  21ma.

Catena con 4 led: Spenti: 16,2 ma; Acceso rosso 1: 17,1; verde e blu idem; bianco 18,8; purple 18ma/giallo; Acceso rosso 1+2: 17,9 ma; verde e blu 18,0 ma; bianco 21,4; purple/giallo 19,6; Accesso rosso 1+2+3: 18,8ma; idem verde e blu;  bianco 24,2; purple/giallo 21,5ma; Acceso rosso 1+2+3+4: 19,8 m; idem verde e blu; bianco 26,7; purple/giallo 23,3.

Si può notare che i colori base (rosso, verde, blu) presentano sempre gli stessi valori così come il giallo e il purple. L’eccezione viene data dal colore bianco. Da prove effettuate con un campione di 12 led e usufruendo di un alimentatore separato (un carica batterie con potenza 1A e quindi separato dal micro) si possono riscontrare i seguenti valori: (valori rilevati con un comune tester con fondo scala a 200ma).

Valore della luminosità (come da funzioni Neopixel) = 25

Tutti i led spenti: ~ 34,3/35ma, 

12 Led accesi colore rosso, verde, blu –> 41,9/42,0;

12 Led accesi colore giallo/rosa: –> 51/51,2;

12 Led accesi color bianco: –> 49,8/49,9

Prove con 16 led: spenti 40ma. Rosso/verde/blu 16 accesi 49/50ma;  

Con questi valori e azzardando una ipotesi, l’assorbimento totale di un quadrante di 28 led dovrebbe essere tra i 100 e i 150mA. E in teoria, l’insieme dei 4 quadranti dovrebbe essere intorno a 400/600 mA.  Ma rimane una teoria allo stato dell’arte avendo effettuato prove con solo 16 led.

Il risultato finale dopo queste prove e dopo la completa realizzazione dell’orologio è che con un carica batterie per telefonini (5V,1A) tutto funziona stabilmente: l’alimentatore dopo 24 ore di funzionamento continuo è rimasto sempre “FREDDO“. Ho tuttavia optato per un alimentatore specifico da 5V,2A per avere una tensione stabile a 5V (i carica batterie a regime hanno una caduta di tensione di quasi 0,5V)  e anch’esso dopo 24 ore è sempre rimasto “FREDDO“.

Un’altra particolarità da tener presente: al momento dell’accensione del sistema (indipendentemente dal numero di led connessi) tutti i led si accendono la massimo della loro luminosità e quindi si può crare un picco di assorbimento. Deve essere previsto quindi il totale spegnimento (via software) immediamente dopo l’avvio del sistema. 

Partiamo allora con le specifiche definitive del progetto:

  1. Quattro display (che chiamerò quadranti), per visualizzare le ore e i minuti. Ogni quadrante viene formato ad immagine e somiglianza di un display a 7 segmenti: ogni segmento è composto da 4 led. Scelta dovuta ad un compromesso tra costo e ingombro.
  2. Due led con lampeggio alternativo in base al valore dei secondi
  3. RTC DS3231 ritenuto più stabile e preciso del Ds1307
  4. Un trimmer analogico per gestire fino a 8 livelli di luminosità modificabile anche a caldo
  5. Un dip_switch a 8 posizioni per scegliere fino a 4 colori per ciascun quadrante modificabili a caldo (due switch per ogni quandrante).
  6. Pulsanti per la regolazione dell’ora e dei minuti in fase di inizializzazione se necessario.
  7. Due pulsanti per l’avvio del sistema e per il reset.

Date queste specifiche l’Hardware utilizzato è il seguente:

  • Micro Arduinio Nano scelto per le dimensioni e per avere già tutto quello che serve: USB per la connessione e il caricamento del software, alimentazione via USB.
  • RTC DS3231 come dispositivo per il mantenimento dei valori del tempo e della data
  • PCF8574 8 bit exapander I2C. Questo dispositivo mi permette di risparmiare per 8 pin di Arduino. Viene utilizzato per leggere i valori impostati nel Dip_Swtich.

Vediamo ora alcuni schemi elettrici del progetto:

Tipica connessione dei led:

Questo schema dimostra (parzialmente) come vengono connessi i led: ogni gruppo di 4 forma un segmento del quadrante: quindi 7 segmenti vengono formati da 28 led totali. Ognuno di questi led è connesso in serie al successivo. Sarà compito del software selezionare opportunamente quale gruppo di 4 led (e quindi un segmento) accendere o spegnere. All’ingresso del primo led viene connessa una resistenza da 470 ohm. (come recitano i sacri testi). Ogni quadrante fa gruppo a se stante: l’uscita dell’ultimo led NON viene connessa con l’ingresso del primo led del quadrante successivo: c’è una ragione specifica. Durante le prove ho notato che questi led sono delicati ed è capitato anche uno “farlocco“. E’ chiaro che essendo tutti in serie è sufficiente che uno solo abbia qualche problema per inficiare tutta la catena successiva. Per evitare questo genere di problemi ho deciso di gestire singolarmente (la libreria lo permette) i 4 quadranti. Ne deriva soltanto una complicazione a livello programmazione nella scelta di quale quadrante utilizzare.

Connessione dispositivi:

In questo schema si mostra come sono stati connessi sia il pcf8574 che l’RTC Ds3231. In realtà questo è uno schema esemplificativo in quanto sia per L’RTC che per Il PCF sono stati utilizzati dispositivi già premontati: sono dispositivi di facile installazione e utilizzano il protocolo I2C. Nello schema era stato previsto anche un ulteriore PCF8574 per la visualizzazione dei secondi in modo binario utilizzando 7 bit. Per non complicare ulteriormente il sistema ho preferito poi usare 2 led con lampeggio alternativo. Nello schema sono visibili anche le connessioni scelte per i pin di Arduino a cui connettere pulsanti e trimmer.

PCB di ogni quadrante:

Questo è il pcb definitivo valido per ogni quadrante. Ne avevo realizzato uno più piccolo ma in pratica con i led da 5mm risultava problematica la connessione in quanto troppo vicini tra loro. Putroppo da come potete vedere nella prima foto complessiva del progetto, la precisione non brilla.

LAYOUT DI OGNI QUADRANTE:

A titolo di esemplificazione ogni quadrante ha la seguente disposizione e numerazione logica di ogni led che lo compone. La tacca di ogni led identifica il pin DATA_OUT

 

PCB del pannello di controllo:

Questo pannello alloggia: il trimmer per la regolazione della luminosità, i 2 pulsanti per l’aggiornamento dei valori ORA e MINUTI, il pulsanti di START del sistema, il pulsante di RESET, il ponticello che a seconda di come viene impostato permette l’aggiornamento in più o in meno dei valori ORA e MINUTI quando devono essere aggiornati, infine l’alloggiamento del dip_swtich per il cambio dei colori ai quadranti.

PCB MAIN:

Questo è il pcb definito “MAIN” in quanto alloggia il micro Arduino_Nano, i vari connettori per i dispositivi I2C e per il pannello di controllo. E’ stato previsto anche un ingresso separato per l’alimentazione dei quadranti (previsto ma poi non utilizzato). L’USB del  micro provvede all’alimentazione del resto del circuito.

PCB BUS_QUADRI e LED_SECONDS

Questi due ultimi pcb sono di supporto: BUS_QUADRI consente il collegamento dei 4 quadranti verso il pcb MAIN con il segnale di ingresso e l’alimentazione ciascuno. LED_SECONDS alloggia i due led che devono lampeggiare al ritmo di un secondo. Questo PCB è situato tre i due quadranti delle ore e i due dei minuti; l’alimentazione e il segnale vengono connessi tramite il BUS_QUADRI.

 

COSTRUZIONE DELL’OROLOGIO

Nella foto sottostante si può notare come è stato costruito l’alloggiamento dei quadranti:

Con un telaio di 28cm con base in legno e laterali in plexiglass sono stati incollati i 4 quadranti come da foto: nel centro i due led per i secondi e a destra il pcb BUS_QUADRI per le connessioni al main. Dato che i led anche la minimo della luminosità sono comunque molto luminosi, per evitare che la luminosità dei singoli led possa coprire quella laterale destra e sinistra, ogni quadrante viene “coperto” da una mascherina nera (plastificata) per evidenziare i singoli segmenti. Ogni segmento è stato avvolto con una striscia di cartoncino nero.  Ecco come si presena a “nudo”.:

Con questo sistema si ottiene una buona visualizzazione “separata” dell’intero orologio senza che la luminosità di un quadrante non interferisca con quella laterale. (Si ricordi che i colori Red,Green, Blu hanno comunque una luminosità diversa l’uno dall’altro).

IL CUORE DEL SISTEMA:

Nella foto sottostante l’immagine del pannello di controllo che chiude una scatoletta in plexiglass dove è alloggiato il micro Arduino_Nano, RTC e il PCf8574 e i connettori verso i quadranti. Il pannello è composto dal trimmer (10K) per la regolazione della luminosità, dai pulsanti per l’aggiornamento delle ORE e dei Minuti. il pulsante di START e il RESET, infine il ponticello per l’aggiornamento un positivo o negativo dei valori del tempo. Sul lato destro il DIP_SWITCH e l’array delle resistenze di pull_up.

 

L’ IMPLEMENTAZIONE DEL SOFTWARE

Se non mi complico la vita non sono soddisfatto: gestire un orologio non è assolutamente difficile se proprio non si è alle prime armi. Avrei potuto fare uno sketch molto semplice limitandomi alla lettura dell’ RTC la decodifica dei valori e l’esposizione sui quadranti.

Ma poi siccome “l’appetito vien mangiando”  ho implementato uno sketch che prevede:

  • Gestione dei 4 quadranti tramite la libreria ADAFRUIT_NEOPIXEL.
  • Gestione dell’ RTC con aggiornamento dei valori quando necessario. (che se rispetto al DS1307 è più preciso, ogni tanto va aggiornato se non altro per l’ora legale/solare).
  • Gestione della luminosità per variare in un range di 8 valori da un limite minimo ad un massimo (anche se non è il massimo sopportabile) tramite un trimmer con lettura analogica.
  • Gestione dei colori dei singoli quadranti: ognuno può avere un colore diverso dal precedente e dal successivo: tramite un DIP_SWITCH si può selezionare uno dei 4 colori definiti: ROSSO, VERDE, BLU, ROSA. Ho scelto questi colori in quanto sono quelli che “consumano meno corrente”.

FILOSOFIA DI GESTIONE:

Come ho già specificato per evitare problemi di connessione o malfunzionamenti vari, ho deciso di gestire i 4 quadranti singolarmente (quindi solo 28 led per quadrante). Ho definito allora 4 istanze della libreria ADAFRUIT_NEOPIXEL per avere la gestione separata di ciascun quadrante. Questo ha comportato sicuramente una complicazione in quanto lo sketch deve provvedere a gestire singolarmente le accensioni e lo spegnimento dei singoli quadranti per le ore e per i minuti. 

All’ atto dell’avvio dello sketch dopo le inizializzazioni della libreria occorre effettuare SUBITO lo spegnimento dei singoli quadranti: questi si accendono con colori casuali e alla massima luminosità. Per spegnere occorre inviare a ciascuna catena il colore ZERO: in pratica il nero. Una alternativa potrebbe essere portare la luminosità = a zero.

Lo sketch prosegue con l’avvio del protocollo WIRE per la gestione dei dispositivi I2C, con la lettura del DIP_SWITCH per determinare i colori, con la lettura del trimmer per la luminosità, quindi inizia la lettura dei valori orari dell’ RTC e effettua subito una visualizzazione delle ore e dei minuti nei rispettivi 4 quadranti. Si pone quindi in attesa della lettura di uno dei pulsanti del pannello di controllo. Se viene premuto il pulsante delle ore aggiorna il valore relativo in più o in meno in funzione della posizione del ponticello “+/-“.  E visualizza subito il valore modificato. Lo stesso avviene per i valori dei minuti se viene premuto il relativo pulsante. La pressione del pulsante “START” innesca il ciclo finale dello sketch: se ci sono stati degli aggiornamenti questi vengono ricaricati nell’ RTC.  Il ciclo perenne legge la posizione del trimmer per variare la luminosità e del Dip_Swtich per i colori effettuando le variazioni del caso. Vengono letti quindi i valori orari dell’ RTC e soltanto se sono variati ne effettua la visualizzazione.

ASSEGNAZIONE PIN ARDUINO:

La sottostante tabella deifinisce come sono stati assegnati i pin di Arduino:

PIN

ASSEGNAZIONE

A0

Input analogico per trimmer luminosità

PIN 2

DataIn quadrante 1

PIN 3

DataIn quadrante 2

PIN 4

DataIn quadrante 3

PIN 5

DataIn quadrante 4

PIN 6

Pulsante ORE (Pull_Up)

PIN 7

Pulsante MINUTI (Pull_Up)

Pin 8

Pulsante START (Pull_Up)

Pin 9

Switch +/- (Pull_Up)

PIN 10

Lampeggio led secondi

PIN A4

SDA per RTC e DS3231

PIN A5

SCL per RTC e DS3231

 

LA LIBRERIA ADAFRUIT_NEOPIXEL:

Scaricata dall’omonimo sito (esistono due versioni una più aggiornata ed un altra che gestisce i NEO_PIXEL RING e le matrici Neo_Pixel) questa libreria con poche funzioni è in grado di gestire un numero quasi illimitato di led WS2812. Le principali funzioni possono essere riassunte come segue:

Per prima cosa occorre istanziare l’oggetto con i seguenti parametri:

Adafruit_NeoPixel pixels = Adafruit_NeoPixel (NUMPIXELS, PIN, NEO_RGB + NEO_KHZ800);

dove: pixels è il nome dato all’istanza,  NUMPIXELS il numero dei led connessi (il primo della catena si identifica con l’offset “ZERO” e in totale sono 28 per quadrante), PIN indentifica il pin digitale di Arduino per connettere il primo DATA_IN del led di ogni catena. (Vedi tabella precednte).  NEO_RGB + NEO_KHZ800 indica che la sequenza dei colori del led sono nel formato R-G-B e la frequenza in 800Hkz. Da alcuni esempi scaricati quest’ultimo valore è pressochè standard. E’ possibile istanziare più oggetti dando a ciascun un nome diverso (ovviamente). Queste definizioni vanno inserite nella sezione variabili.

Nella sezione SETUP occorre per ogni istanza inizializzare la libreria con: nome_istanza.begin(). Nello sketch ci sono quindi 4 di queste frasi.

Le successive funzioni effettuano la gestione effettiva di ciascuna istanza (e relativa catena associata). La luminosità viene gestita con al funzione: nome_istanza.setBrightness(valore) e viene applicata all’intera catena dei led.

L’accensione di ogni led di una catena (ricodiamoci sono 28 per catena) avviene indicando sia la posizione del led (il suo offset partendo da zero) che il colore da assegnare. Ne deriva che per ogni led della catena è possibile assegnare un colore diverso. La funzione ha due formati:

nome_istanza.setPixelColor(Led_Offset,nome_istanza.Color(r,g,b));  con questo si devolve alla libreria la codifica del colore secondo i valori definiti in r1,g1,b1 (da o a 255), in alternativa il secondi formato definisce direttamene il codice colore (32 bit unsigned): nome_istanza.setPixelColor(Led_Offset,codice_colore).

Nello sketch viene effettuato un ciclo di 28 iterazioni per assegnare e quindi accendere un segmento della catena dei led di ogni quadrante.

Tutto ciò non porterebbe a nessun risultato se non venisse eseguita la funzione: nome_instanza.show(). Questa funzione deve essere sempre eseguita se vogliamo vedere accendere o spegnere i led o modificarne la luminosità.

C’è una riflessione da fare circa l’uso di quest’ultima funzione: se si tratta di accendere/spegnere un solo led o variarne la luminosità dopo la funzione specifica, è sufficiente lanciare la funzione show() per eseguire quanto programmato. Se però (nel caso specifico) i led da accendere/spegnere sono più di uno si possono utilizzare due tecniche: nel ciclo eseguire la funzione specifica di accensione/spegnimento  e alla fine del ciclo eseguire la funzione show() oppure durante lo stesso ciclo eseguire di seguito la funzione show().

Ecco un esempio (tratto allo sketch). La routine che spegne i led: NQ il numero della catena da 1 a 4 in quanto è la routine prevede lo spegimento di un solo quadrante o di tutti (NQ = 0).

void Spegnimento(byte NQ)
{ int kl;
  if (NQ == 0 || NQ == 1)
   { for (kl = 0; kl < NUMPIXELS; kl++) QDR_DEC_ORE.setPixelColor(kl,0);
    QDR_DEC_ORE.show(); }

In questo caso la funzione show() viene eseguita alla fine del ciclo for.

In questo esempio la lumimosità viene modificata soltanto se dopo viene eseguita la funzione show():

QDR_DEC_ORE.setBrightness(Lumen_Value);
QDR_DEC_ORE.show();

Un’altra funzione della libreria permette di rilevare il colore assegnato al led: ritorna il codice del colore nel formato  32 bit unsigned: nome_istanza.getPixelColor(Led_Offset).

 

CONCLUSIONE:

Spero di aver sufficentemente esposto questo progetto che dal mese di  marzo ad oggi ha occupato quel poco di tempo libero a disposizione. Di solito non dedico più di 2 ore al giorno a questo hobby: ho una certa esperienza in programmazione per cui è difficile che abbia problemi si programmazione. Sto pensando ad un upgrandig del progetto: inserire anche la visualizzazione della temperatura visto che il DS3231 alloggia anche il sensore e la modifica casuale dei colori. Vedremo….

Ringrazio comunque tutti gli ElettroAmici per il tempo che hanno dedicato a leggere questo articolo. So di essere ripetitivo…..questo è l’ennesimo orologio. In ogni caso sono a disposizione per chi volesse documentazione o altro in merito a questo progetto.

Grazie

Gvsoft Gugno 2019

gvsoft75@hotmail.com

VOTO
2 commenti
  1. Amilcare
    Amilcare dice:

    Ottimo come ormai ci hai abituati.
    Ho aggiunto al tuo articolo la possibilità di espandere un pochino gli schemi anche se più di tanto non si può vista la bassa risoluzione delle immagini stesse, comunque meglio di niente sarà

    Approvazioni
    • gvsoft
      gvsoft dice:

      Grazie, Amilcare, anche se con notevole ritardo, ma ho avuto qualche problema di salute che dovrebbe risolversi lunedì 15 cm.
      Volevo lasciare un commento ma ovviamente non posso commentare un mio articolo. Allora approfitto in questa risposta per fornire alcuni suggerimenti a chi può essere interessato all’uso di questi led. Munirsi di un buon alimentatore da 5V o 3V da almento 2A. Mettere un condensatore da 1000 uf all’uscita dell’alimentatore. Controllare uno per uno tutti i led da usare: avevo fatto un piccolo pcb per provare uina catena di 8 led scoprendo così che qualche led è “farlocco” e quelli che lo seguono “impazziscono”. Se non si ha la possibilità di fare PCB professionali verificare bene le piste specialmente quella che collega DOUT con DIN. Alla fine della catena (o all’inizio) inserire un consensatore ceramico (codice 104). Tener presente che al momento della accensione del sistema tutti i led si accendono alla massima luminosità di solito di colore azzurro e alcuni bianco: ciò implica un picco di potenza assorbita. Quindi la prima cosa da fare dopo la funzione begin() è spegnere la catena con la funzione show() oppure con un ciclo che invia ad ogni led il colore nero (Rgb: 0,0,0).
      Non ci sono limitazioni al numero dei led in catena, ma, come si può vedere nell’articolo, i 112 led sono gestiti da 4 catene diverse. Ciò implica una complicazione nella programmazione ma può semplificare e risolvere meglio qualche problema di funzionamento: nella fattispecie il primo quadrante (decine di ore) dopo qualche ora ha cominciato a dare problemi e ho dovuto farne uno nuovo: probabilmente c’era un led “farlocco” quando voleva lui però !!!!.
      Grazie ancora Amilcare

      Approvazioni

Lascia un Commento

Vuoi partecipare alla discussione?
Fornisci il tuo contributo!

Lascia un commento