Non è necessario un RTC per costruire un orologio: il chip ATmega ha tutto l'hardware necessario per svolgere le funzioni dell'RTC stesso. Ecco come:
Ottieni un cristallo da 32768 Hz: acquistalo o disassembla un vecchio orologio. Questi cristalli, appositamente progettati per il mantenimento del tempo, hanno una deriva della temperatura estremamente piccola. Ne avresti bisogno anche uno se volessi usare un chip RTC.
Configura i fusibili del tuo ATmega per far funzionare l'oscillatore RC a 8 MHz. Ciò renderà la tua millis()
funzione orribilmente inaccurata e libererà anche i pin XTAL1 e XTAL2.
Collegare il cristallo dell'orologio ai pin TOSC1 e TOSC2. Questi sono gli stessi pin di XTAL1 e XTAL2 (9 e 10 su 328P). I nomi diversi sono usati per indicare funzioni diverse.
Configurare il Timer / Contatore 2 per il funzionamento asincrono, la modalità di conteggio normale, il prescaler impostato su 128 e abilitare l'interruzione di overflow del timer.
Ora otterrai un interrupt TIMER2_OVF a una velocità molto costante di una volta al secondo. Nell'ISR è sufficiente far avanzare il display dell'orologio di un secondo. Tra una pausa e l'altra, puoi mettere l'MCU in modalità di sospensione molto profonda (modalità di risparmio energetico: niente funziona se non Timer / Counter 2) e correre per anni su un paio di celle AA. A meno che il display non abbia fame di energia, ovviamente.
Ho fatto esattamente questo per costruire il mio orologio da parete 24 ore con una mano . Questo link punta ora alla traduzione inglese della documentazione originale in francese.
Calibrazione al quarzo
Se non si calibra il quarzo, è possibile prevedere una deriva significativa, in genere alcuni secondi alla settimana . La velocità di deriva dipende dalla capacità parassita delle tracce che collegano il cristallo all'MCU. In linea di principio, potrebbe essere rimosso aggiungendo una capacità extra, finemente sintonizzata. Vale la pena notare che si avrebbe lo stesso problema di deriva con un RTC.
Se sei soddisfatto di questo tipo di precisione, vivi con esso e sii felice. Tuttavia, se ti interessa misurare la deriva, noterai che è molto stabile. È quindi possibile compensarlo facilmente nel software e ottenere una precisione di pochi secondi all'anno .
L'algoritmo per correggere la deriva è molto semplice. Dalla deriva misurata, si capisce il ritardo preciso tra gli interrupt, che dovrebbe essere molto vicino a 10 9 nanosecondi, quindi:
#define ONE_SECOND 1000000000 // in nanoseconds
#define ONE_INTERRUPT 999993482 // for example
ISR(TIMER2_OVF_vect)
{
static uint32_t unaccounted_time;
unaccounted_time += ONE_INTERRUPT;
while (unaccounted_time >= ONE_SECOND) {
advance_display_by_one_second();
unaccounted_time -= ONE_SECOND;
}
}
Nell'esempio sopra, il quarzo è leggermente troppo veloce e il software compensa "mancando" un segno di spunta ogni pochi giorni. Se il quarzo fosse troppo lento, lo stesso codice farebbe invece doppio segno di spunta una volta ogni pochi giorni.
Questo tipo di calibrazione potrebbe anche essere fatto per un RTC, ma sarebbe significativamente più complesso perché l'RTC riporta il tempo in una forma scomposta che non si presta naturalmente alle operazioni aritmetiche.