In questo articolo vi presento il Micrologio, un micro-orologio basato su un Atmega328P. La differenza rispetto ad altri è che questo progetto è stato uno studio per diverse tecniche da usare con i microcontrollori, ossia il multiplexing per pilotare direttamente un display LED a 7 segmenti, il risparmio energetico spinto per poter alimentare l’orologio con una batteria tipo CR2032, l’utilizzo del modulo Real-Time Counter del microcontrollore per poter tenere l’ora senza un RTC esterno. Grazie a tutti questi accorgimenti il Micrologio è piccolo, utilizza un numero esiguo di componenti e consuma pochissimo.
Partiamo dalla lista dei componenti:
- basetta millefori per assemblaggio del progetto
- MCU Atmel Atmega328P o, alternativamente, Atmega168P
- 1 pulsantino switch
- 2 condensatori ceramici da 0,1 uF
- 5 resistenze da 47 ohm 1/4 watt
- 1 resistenza da 22K ohm 1/4 watt
- 1 quarzo da 32768 Hz (Cl di 12,5 pF)
- 2 condensatori ceramici da 22 pF
- 1 display LED a 7 segmenti di colore rosso anodo comune (io ho usato questo: China Young Sun Led Technology Co. Ltd YSD-439AR6B-35)
- 1 batteria a bottone tipo CR2032 con relativo portabatterie
- filo Wire Wrap per i collegamenti
Lo schema per l’assemblaggio da seguire è il seguente:
Precisazione: le resistenze sui piedini 23..27 sono calcolate per operare con la tensione di 3V fornita dalla batteria. Se intendete alimentare il Micrologio con un’altra tensione, dovete ricalcolare il loro valore.
Realizzazione: il montaggio su millefori è abbastanza semplice. Basta seguire lo schema e la disposizione dei componenti che più vi aggrada. Per i ponticelli io ho usato del filo Wire wrap ma potete usare qualche altro tipo di filo. Qui sotto la foto della parte posteriore.
Il firmware per il microcontrollore è scaricabile da questo link. E’ scritto per l’Arduino IDE 002x e necessita della libreria PinChangeInt. Ricordo che i fuse del microcontrollore devono essere programmati con questi valori:
- low fuse: $62
- high fuse: $D2
- extended fuse: $FF
Questi valori impostano l’oscillatore interno ad 8 MHz ed il divisore ad 8x per ottenere un clock finale di 1 MHz.
Analisi del progetto
Il filo conduttore di questo progetto è stato la riduzione dei componenti e dei consumi, in modo da ottenere un oggetto compatto e che funzionasse per molto tempo anche con una piccola batteria. Per ridurre il numero dei componenti ho deciso di eliminare driver esterni per il display e di utilizzare direttamente l’Atmega. Il problema che ho dovuto affrontare è stato quello del non superamento della corrente erogabile da un singolo pin del microcontrollore, che Atmel suggerisce essere di 20 mA.Per fare ciò ho utilizzato la tecnica del multiplexing, ossia il codice pilota un segmento per volta, alternando le cifre in modo da sfruttare il fenomeno detto “persistenza della visione” dell’occhio umano per far vedere all’utilizzatore i numeri nella sua completezza anche se in realtà si tratta di un’accensione sequenziale molto veloce.
Per eliminare il chip RTC esterno ho utilizzato il modulo Real-Time Counter del microcontrollore: questo modulo, se pilotato con un quarzo esterno da 32768 Hz ed un prescaler di 128, permette di ottenere una frequenza perfetta di 1 Hz, ossia di un overflow del contatore ogni secondo. All’overflow agganciamo un interrupt che aggiorna l’orario in modo che ad ogni overflow incrementiamo il contatore dei secondi e, a ruota, tutti gli altri (minuti, ore, giorni, ecc…). Inoltre il modulo RTC funziona anche in modalità risparmio energetico per cui possiamo mettere il microcontrollore in sleep e contemporaneamente avere il modulo RTC che continua a contare a lavorare.
Per ridurre i consumi, oltre ad abbassare la frequenza ad 1 MHz e la tensione di alimentazione a 3V, ho disattivato tutte le periferiche interne al microcontrollore che non avrei utilizzato, ad esempio il convertitore analogico/digitale, il timer 1, l’SPI, la seriale ecc…
Grazie a questi accorgimenti ho raggiunto un consumo di circa 2,5 mA in modalità attiva ed un consumo in modalità sleep che oscilla fra 1 e 2 uA (microAmpere)! Tenendo conto che il micro si sveglia solo 1 volta al secondo per pochissimo tempo per aggiornare l’orologio interno, con una batteria a bottone da 200 mAh possiamo ottenere una durata di più di 10 anni. Considerando che comunque l’orologio verrà svegliato dall’utente per verificare l’ora mediamente qualche volta al giorno, posso prevedere una durata minima di qualche anno, superiore comunque al tempo di autoscarica della batteria.
Aggiornamenti di versione:
- nuova versione 0.4.2, con un nuovo schema di multiplexing ed alcuni bug del codice sistemati. Nuovo menu di programmazione, con setup dell’orario e della data separati ed un nuovo sotto-menu per la regolazione delle impostazioni dell’orologio (schema del multiplexing e secondi di attesa prima della disattivazione del display).
Hi, I really need your help… I have been stuck with makinga a RTC in atmega328p… I now have:
*8MHz bootloader for the internal clock
*Changed the fusebit so that the firmware is uploaded with correct fuse bits.
All I want is to just plot the time in “Serial.print”
Sounds easy, but i just cant get the hang of it…
//Best regards Samir from Sweden
Try looking at my swRTC library that has a couple of examples that “print” the time on the serial terminal.
It works for several clock speeds.
Ciao Leonardo, una domanda… Se invece di far spegnere il display dopo un tot di secondi, lo volessi tenere acceso sempre (anche a discapito della batteria, ma utilizzerei 2 stilo da 1.5) quale parte dovrei andare a modificare? Grazie, Stefano.
Va rivisto un pò tutto il loop perché il codice presuppone di mettere in sleep il chip e di attivare un interrupt per il risveglio. Dovresti eliminare tutta l’attuale funzione loop() e poi rinominare la funzione mainLoop() in loop(). A questo punto rimuovi la chiamata a clockOff(), rimuovi quindi anche la funzione stessa che non serve più, poi metti il codice presente in clockOn() dentro al setup. Rimuovi tutte le chiamate a clockOn/clockOff che trovi a giro. Elimina tutta la parte relativa agli interrupt e poi… prova 🙂
Ciao, grazie per la risposta. Mi puoi aiutare tu? Non sono molto esperto con la programmazione… Scusami…
Non ho al momento il tempo necessario a fare le modifiche che ti ho illustrato. Sto terminando un progetto che mi occupa tutto quel poco di tempo libero che ho. Forse in un futuro rilascerò una versione modificata del Micrologio per funzionare con un’alimentazione a batteria ma ora non ce la faccio proprio.
Ciao,
There is long time I search some that . Thanks a lot;
However, I have a question abour the accuracy drift . If I use this system outdoor ( -15°C to 50°C ) do you think I can have less than 20 min drift on a year ?
Is the drift directely by the crystal oscillator and asociate capacitor ?
Could you tell me what is the drift since you have it ?
Merci beaucoup !
Accuracy depends mainly on the environment temperature. Usually common electronics components are tested to work at 25°C.
If the temperature moves too far from this value, the components may loose accuracy. The amount is not predictable but you can try to find in the data sheets of the components (your Atmega328P and your 32 Khz crystal) how is the deviation from the reference values.
Ciao Leonardo, grazie per l’utilissimo articolo.
Ti faccio una domanda: se volessi utilizzare il tuo progetto su un MCU ATMEL 644p devo diventare pazzo nelle modifiche?
immagino che qualche registro vada cambiato (tipo PRR->PRR0 ….)
Mi interessa sapere cosa ne pensi.
Ciao e grazie ancora