Arduino e Multiplexing - Micrologio

Alcuni giorni fa ho comprato un piccolo display Led a 4 cifre a 7 segmenti (questo per l'esattezza). Solo dopo l'acquisto, leggendo il datasheet, mi sono accorto che era ad anodo comune e quindi non potevo pilotarlo con un MAX7219 che avevo in casa.

Ho deciso perciò di lavorare con il MULTIPLEXING in modo da risolvere la questione "tra me e lui", senza librerie extra né componenti aggiuntivi. Per farmi un piccolo orologio da tavolo a batteria, ho deciso anche di limitare al massimo il numero dei componenti accessori e ne è venuto fuori un piccolo oggetto, che usa il minimo di componenti elettronici:

  • 1 Atmega168 (dovevo riciclarlo dal precedente test dell'Avr-cdc)
  • 1 quarzo da 4 MHz con 2 C da 22pF
  • 2 C da 0.1uF
  • 5 R da 82 ohm
    -1 pulsantino

Il display è pilotato interamente tramite l'Atmega, nessun componente attivo extra, solo le 5 R da 82 ohm per limitare la corrente di alimentazione dei segmenti (ogni segmento è un Led da 3,2V/20mA).
Il problema dell'anodo comune l'ho risolto multiplexando al massimo il display. Ho deciso non solo di pilotare 1 singola cifra per volta (per evitare di cuocere l'Atmega) ma ho deciso anche, vista l'alimentazione a batteria, di accendere anche 1 solo segmento alla volta. In questo modo la massima corrente che l'Atmega168 eroga in ogni istante è di soli 20 mA! In pratica, l'Atmega costruisce la 1a cifra accendendo/spengendo i vari segmenti interessati, poi passa alla 2a e ripete l'operazione, poi alla 3a ed infine alla 4a. E di nuovo da capo.
Dopo 5 secondi, il display viene spento.

Per limitare i componenti ho inserito 1 solo pulsantino. Premendolo 1 sola volta, compare l'ora, ripremendolo si passa alla visualizzazione (in ordine) della data, dell'anno e dei secondi. Dopo 5 secondi si spenge.

Se si preme il pulsantino per più di 1 secondo e mezzo, si entra in modalità programmazione, ed è possibile impostare orario, data e anno dell'orologio.

Ovviamente ho usato la mia swRTC (leggermente modificata per supportare i 4 MHz) per evitare l'uso di un RTC aggiuntivo. Grazie al quarzo esterno, la libreria dovrebbe essere abbastanza precisa, sicuramente precisa quanto un comune orologio da parete.

In allegato la foto del prototipo realizzato su 1000fori (noterete 2 connettori per l'alimentazione, uno a DX ed uno in alto, perché inizialmente provavo il circuito con un pacco batterie che ha uno spinottino autocostruito). Il circuito (minimalista) e lo sketch sono in allegato. Aggiungo anche un video per far vedere come funziona il tutto. Ho notato che il multiplexing permette di risparmiare corrente ma riduce sensibilmente la luminosità apparente dei segmenti. Io ho usato un display con cifre bianche, forse con quelli a cifre rosse o bu, di colore più "forte", forse la situazione è migliore. Lo sketch può essere modificato per attivare un multiplexing differente, ad esempio si può pensare di pilotare tutti i segmenti di una cifra alla volta, ma per far ciò è bene usare un transistor pilotato dai pin dell'Arduino perché "aprendo" l'output ed ipotizzando di accendere tutti i 7 segmenti di una cifra, si arriva a "succhiare" dal pin ben 140 mA, e tutti sappiamo che più di 20 mA non possono uscire da un singolo GPIO.

Video della versione definitiva (vedi post più avanti):

EDIT:
messo nello zip il file .sch per Eagle dello schema del circuito. Attenzione: è stato creato con Eagle 6.2, Eagle 5.x non lo apre.

Micrologio.zip (960 KB)

micrologio2.pde (13.3 KB)

Bella idea, complimenti.

Puoi sempre usare il MAX7219 in modalitá matrice ma devi ricalcolarti i valori da mettere nei singoli registri LED accesi per avere i numeri corrispondenti. Multiplexando col Atmega consumerai meno correnete rispetto alla combianzione ATmega-MAX.

Per il multiplexing di un singolo segmento oppure di piú segmenti vorrei considerare che a paritá di lumiositá il consumo potrebbe essere simile. Se lasci acceso i segmenti per piú tempo possono essere meno luminosi e percui assorbire meno corrente.

Ciao Uwe

bello, complimenti.

e' normale che multiplexando sia meno luminoso, in quanto nell'istante X tieni acceso un solo segmento su 28, la luminosita' e' inferiore e non di poco.

Secondo me hai multiplexato "troppo", invece di avere 1 segmento su 28, la cosa migliore e' accendere 4 segmenti su 28, cioe' uno per cifra.

Passerai ad una luminosita' di 3 volte superiore, usando 80mA a ciclo ma su 4 pin diversi, 20ciascuno

@Uwe:
Ho deciso di eliminare del tutto i componenti esterni proprio per: ridurre il consumo complessivo del circuito, ridurre l'ingombro dello stesso.

Ho fatto diversi esperimenti con il multiplexing, in questi 2 giorni, ho notato alla fine una cosa. Se aumenti il tempo di accensione di ogni singolo segmento, poi il display "sfarfalla" lo stesso perché il micro impiega molto più tempo a fare il refresh di ogni singola immagine (considera che deve partire dal 1° segmento della 1a cifra ed arrivare al 7° segmento della 4a cifra). Anche la frequenza incide notevolmente. Se a 16 ed 8 MHz non ci sono problemi, a 4 MHz ho dovuto ridurre di molto il tempo di accensione dei segmenti mentre ad 1 MHz ho dovuto addirittura togliere il tempo di attesa tra l'accensione e lo spegnimento e nonostante questo il tempo non è sufficiente a compiere tutto il ciclo senza che l'occhio se ne accorga. Ecco perché alla fine ho optato per 4 MHz.

Volendo si può ridurre ulteriormente il consumo impostando il micro a 3,6V (la tensione di 3 batterie ricaricabili da 1,2V) e ricalcolando le R di limitazione.

Ah, internamente allo sketch ho disattivato via software tutte le periferiche non usate: timer 1, SPI, USART, ADC ecc...

@testato:
Sì, avevo valutato questa soluzione. Ma l'ho scartata considerando appunto l'alimentazione a batterie.
Se invece uno sceglie di alimentare il circuito con un piccolo alimentatorino a parete da 5V, allora può modificare il codice e visualizzare come hai detto tu 4 segmenti per volta, 1 per ognuna delle 4 cifre (tot 80 mA).

capisco,
quanto assorbe da acceso e da spento ?

  • la foto e' sfuocata
  • nello schema non e' segnata la tensione di alimentazione
  • nello schema manca il modello del display (c'e' la marca non il tipo esatto)
  • se posti anche il file .sch chi vuole farsi il pcb deve solo "sbrogliare" :slight_smile:
  • visto che parli di swRTC modificata sarebbe corretto postare anche quella ?

basta ora, rinnovo i complimenti :slight_smile:

Non credo che puoi alimentare il tutto con 3,6V perché il display a colore bianco ha un Uf di 3,4V. Cosí non resta una differenza di tensione per la resistenza limitazione corrente LEd.
Ciao Uwe

@Uwe:
in teoria il datasheet di quel display dà una tensione minima di 3,2V per i led per cui si ha una differenza di 0,4V, dovrebbero bastare per mettere una piccola R da 18 ohm.

@Testato:
non so perché ma la macchinetta ieri mi ha fatto foto e filmato entrambi sfuocati :stuck_out_tongue:
la tensione di alimentazione è 5V, non l'ho messa nello schema ma l'ho indicata nel post. Ho messo il PDF perché uso Eagle 6.2 e non tutti ce l'hanno, quindi non tutti potrebbero aprire il file .sch. Cmq lo posto lo stesso. Il modello del display lo recuperi dal link dove l'ho comprato. Per la swRTC è in arrivo, ci stavo lavorando per mettere i 4 MHz anche per gli altri modelli. A proposito, ora vado a rivedere nel thread cos'è che chiedevi che aggiornassi quando ci rimettevo le mani :wink:

Il range di tensione dei LED a una correnete di 20mA va da 3,2 fino a 3,5V con un valore tipico di 3,4V.
La differenza é dato da differenze nella produzione dei led.
Non considerando la perdita di tensione sul transistore interno del ATmega hai una tensione utile da 0,1V a 0,4V con un alimentazione di 3,6V.
Che corrisponde teoreticamente a una corrente 4 volte maggiore tra un led e l'altro.

Visto che un accumulatore NiMH arriva anche a 1,4V quando é pieno e a 1V se é vuoto (4,2V e 3V) hai anche quá una notevole differenza che fa che la corrente attraverso il LED é tutt'altro che stabile.

Questo é il problema con tensioni cosí oiccole che puoi usare sulle resistenze limitatrici.

Ciao Uwe

Ho messo una foto più nitida.
Ho anche messo lo schema del circuito aggiornato, mi sono accorto che avevo inserito una versione vecchia, con un solo C di disaccoppiamento per le alimentazioni dell'Atmega. Ho anche inserito il modello del display.

Un unico appunto: il file .sch è stato fatto con Eagle 6.2, le versioni 5.x del programma non possono aprirlo.

ora va meglio :slight_smile:
cmq e' buona norma lasciare anche l'immagine, in modo che chi non usa eagle puo' vedere lo schema, o guardarlo al volo, puoi farlo pdf o lasciarlo come immagine
Rompo troppo ? Lo faccio per te :slight_smile:

leo72:
A proposito, ora vado a rivedere nel thread cos'è che chiedevi che aggiornassi quando ci rimettevo le mani :wink:

il getWeekDay :slight_smile:

Testato:
capisco,
quanto assorbe da acceso e da spento ?

Non ho misurato i consumi.

Testato:
ora va meglio :slight_smile:
cmq e' buona norma lasciare anche l'immagine, in modo che chi non usa eagle puo' vedere lo schema, o guardarlo al volo, puoi farlo pdf o lasciarlo come immagine
Rompo troppo ? Lo faccio per te :slight_smile:

Rielaboro il PDF, come detto il precedente schema non era quello finale.

Testato:

leo72:
A proposito, ora vado a rivedere nel thread cos'è che chiedevi che aggiornassi quando ci rimettevo le mani :wink:

il getWeekDay :slight_smile:

Testato:

leo72:
A proposito, ora vado a rivedere nel thread cos'è che chiedevi che aggiornassi quando ci rimettevo le mani :wink:

il getWeekDay :slight_smile:

Cioè? Avere il numero del giorno della settimana della data corrente, giusto? Lo metto domani.

Una stupidagine, però per risparmiare ancora spazio puoi usare un risuonatore invece dell'oscillatore più i condensatori. ...a meno che non ci sono controindicazioni che non so...

Complimenti.
Davide.

dab77:
Una stupidagine, però per risparmiare ancora spazio puoi usare un risuonatore invece dell'oscillatore più i condensatori. ...a meno che non ci sono controindicazioni che non so...

La precisione. Il quarzo ha una precisione molto maggiore, e siccome l'MCU deve mantenere anche l'ora il risuonatore così come l'oscillatore interni li ho scartati a priori. Anzi, l'idea iniziale prevedeva l'uso di un quarzo esterno da 32768 Hz collegato ed il modulo Real-time counter interno attivo, con il micro che doveva lavorare a 1 MHz con l'oscillatore interno ma i problemi di refresh del display per il multiplexing mi hanno fatto ripiegare su questa soluzione.

Adesso voglio studiare una soluzione alternativa, questa votata alla riduzione massima dei consumi. Vi terrò aggiornati.

leo72:

dab77:
Una stupidagine, però per risparmiare ancora spazio puoi usare un risuonatore invece dell'oscillatore più i condensatori. ...a meno che non ci sono controindicazioni che non so...

La precisione. Il quarzo ha una precisione molto maggiore, e siccome l'MCU deve mantenere anche l'ora il risuonatore così come l'oscillatore interni li ho scartati a priori. Anzi, l'idea iniziale prevedeva l'uso di un quarzo esterno da 32768 Hz collegato ed il modulo Real-time counter interno attivo, con il micro che doveva lavorare a 1 MHz con l'oscillatore interno ma i problemi di refresh del display per il multiplexing mi hanno fatto ripiegare su questa soluzione.

Adesso voglio studiare una soluzione alternativa, questa votata alla riduzione massima dei consumi. Vi terrò aggiornati.

Ok, Grazie!

devi cambiare display :slight_smile:
ci sono gli Oled seriali, consumo zero e comodita' di gestione

Io sono più un firmwarista che un elettronico, lo sai :wink:

certo, ed infatti hai fatto un ottimo lavoro, talmente ottimo che credo non ci sia altro da migliorare.
perche' per ridurre i consumi dovresti scendere di velocita', ma questo porta a flickering del display, per ridurre il flickering potresti diminuire il livello di multiplex, ma questo aumenta i consumi.
come vedi non se ne esce, per questo dico che piu' che migliorare questo c'e' da cambiare display

Mah, ora ho un paio di idee per migliorarlo, ve le esporrò a breve quando arriveranno le cose che ho acquistato.
Poi ho già un'altra idea da sviluppare.... roba completamente differente. 8)