Come posso ottenere un orario preciso?


16

Ho realizzato un orologio usando un Arduino, ma il tempo sembra andare alla deriva. Sono a conoscenza del problema del rollover ; l'orologio sembra andare alla deriva di circa 15 minuti nel corso di una settimana.

Sto usando un PCB personalizzato con questo risonatore di Digi-key. Il codice legge la funzione millis () all'inizio di ogni ciclo e funziona da quel valore.

La mia domanda è: come posso misurare il tempo con un Arduino, abbastanza accuratamente da rendere un orologio da scrivania passabile?


3
La funzione in millisecondi viene fornita con i dati di un interrupt, che richiede l'esecuzione di un paio di cicli di clock. Questo aggiunge un minimo di tempo ad ogni tick.
TheDoctor,

3
@TheDoctor: questo non è corretto. L'interruzione non rallenta il timer hardware che guida millis().
Edgar Bonet,

Risposte:


15

Nota: sebbene la mia risposta sia stata accettata e abbia un punteggio più alto, assicurati di leggere l'ottima risposta di Edgar Bonet su come far sì che il tuo Arduino tenga il tempo senza un RTC.

Ho avuto abbastanza successo nell'utilizzo dell'orologio in tempo reale DS1307. Ecco un link al suo foglio dati .

Di seguito alcune delle sue caratteristiche:

  • Utilizza l'interfaccia IC per la comunicazione con Arduino, facilitando la programmazione utilizzando le librerie giuste (disponibili in rete).

  • È collegato ad Arduino tramite i pin SCL e SDA (rispettivamente A4 e A5 analogici), quindi utilizzando solo 2 pin.

  • Richiede pochissimi componenti esterni per funzionare.

  • L'IT può essere collegato a una batteria a bottone in modo da mantenere il tempo anche quando Arduino è spento. Nella sua modalità a basso consumo, la batteria a bottone dura anni.

  • Va alla deriva molto poco (nel mio caso va alla deriva solo pochi secondi alla settimana).

  • Non è molto costoso.

Se non si intende utilizzare un RTC, è possibile sostituire il cristallo che viene comunemente utilizzato per fornire l'orologio ad Arduino per un modulo oscillatore a cristallo come questo da Farnel o quest'altro . Sono disponibili in pacchetti da 4 pin come nelle immagini sottostanti. Genereranno un orologio molto più preciso per il tuo arduino.

Immagine dell'oscillatore a cristallo Immagine dell'oscillatore a cristallo Immagine dell'oscillatore a cristallo

Entrambi i moduli citati hanno tolleranze di 50 ppm e funzionano a 5V.

Ancora una volta, solo per essere chiari, questi moduli oscillatore a cristallo non devono essere confusi con il normale cristallo a 2 pin come questo di seguito. Questi fanno parte del circuito di orologi esterni per MCU, ad esempio.

Oscillatore a cristallo


DS1302 è abbastanza buono o devo spostarmi su DS1307?
Kelly S. francese,

14

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:

  1. 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.

  2. 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.

  3. 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.

  4. 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.


Wow, questo è un design davvero elegante! Mi piace molto come hai messo su abbastanza foto per rendere chiaro il design, anche per noi stupidi americani monoglot :) :) Adoro vedere la documentazione esplicita del progetto come questa!
John Walthour,

2
@JohnWalthour: grazie! Ora mi stai incoraggiando a scrivere una traduzione. :-)
Edgar Bonet,

2
@JohnWalthour: Fatto! Il collegamento ora punta alla traduzione inglese.
Edgar Bonet,

Giusto per essere chiari, quando dici "Il chip ATmega ha tutto l'hardware necessario", non è del tutto vero quando devi ottenere un nuovo cristallo. Penso che la tua soluzione sia liscia e non sto sostituendo il cristallo, ma ero un po 'confuso quando dici che non ho bisogno di hardware e poi mi giro e dici che devo sostituire un pezzo di hardware.
Kelly S. francese,

@ KellyS.French: La mia frase è stata "il chip ATmega ha tutto l'hardware necessario per eseguire le funzioni dell'RTC stesso" (enfasi aggiunta). Ma è importante notare che la maggior parte dei RTC, incluso l'onnipresente DS1307, ha bisogno di un cristallo esterno per funzionare. L'ATmega non è diverso: ha tutto ciò che serve per sostituire l'RTC stesso , ma non per sostituire il cristallo che dovresti comunque connettere all'RTC. Si noti che un modulo RTC è più di un semplice RTC, poiché include il cristallo.
Edgar Bonet,

6

Il risonatore che hai specificato ha una stabilità dello 0,3%, dove l'oscillatore di cristallo o cristallo (come menzionato da Ricardo) è di 50 ppm. Molte volte più stabile. Per non parlare della deriva della temperatura del risonatore è orribile. Il riscaldamento con la luce solare lo cambierà. Quindi un risuonatore non dovrebbe essere usato per mantenere il tempo per lunghi periodi.

Quindi usando un oscillatore a cristallo o cristallo otterrai ciò che desideri. O usandolo su ATmega e impostare i fusibili rispettivamente o noi uno collegato a un RTC.


Dove 50 ppm è una stabilità dello 0,005%?
Matthew G.

Mi generalizzo su quella specifica, per rispondere brevemente. Nota stabilità a parte Ris. hanno una tolleranza molto più grande e possono essere abbastanza fuori. Come sta vivendo John W. "la parte giusta per il lavoro giusto"
mpflaga,

Oh, ero solo curioso di terminologia @mpflaga ... nuovo per me.
Matthew G.

4

Se non si desidera utilizzare hardware aggiuntivo come un Real Time Clock (ad es. DSDS1307), è possibile migliorare in modo significativo la precisione della temporizzazione disabilitando tutti gli interrupt non utilizzati. Per impostazione predefinita, gli schizzi di Arduino sono dotati di varie routine di interruzione abilitate e spesso non vengono utilizzati per lo schizzo. Il modo più rapido per scoprire se puoi farne a meno per provare a disabilitarli emettendonoInterrupts();


3
−1 (anche se questo merita −4) perché: 1. A meno che non siano effettivamente necessari, tutti gli interrupt sono disabilitati per impostazione predefinita, con la sola eccezione di TIMER0_OVF, necessaria per il mantenimento del tempo. 2. L'accuratezza dei tempi degli Arduinos è limitata principalmente dalla qualità del risonatore. 3. Gli interrupt non influiscono sulla precisione a millis()meno che non si riesca a spendere più di un millisecondo alla volta per ripararli, nel qual caso si hanno altri problemi ... 4. Disabilitare gli interrupt con noInterrupts()impedirà millis()di non perdere tempo!
Edgar Bonet,

2

Capisco molto dello spirito con Arduino che è stato frugale e ogni tanto arrancando attraverso un problema. Uso Arduino (e ora chipKIT, dato che ha 10 volte la RAM e 10 volte la velocità di clock) per il mio posto di lavoro e ho bisogno di "funzioni periferiche" per essere al passo con la velocità e lavorare il più rapidamente possibile.

Uso l'orologio Sparkfun in tempo reale in uno dei miei progetti e ne sono molto contento. Hanno anche una variante "Dead on" .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.