Go Down

Topic: Oscillatori esterni e timer (Read 223 times) previous topic - next topic

Ketto

Sep 23, 2019, 07:35 pm Last Edit: Sep 23, 2019, 07:37 pm by Ketto
Salve a tutti, da tempo voglio sviluppare un cronometro molto preciso per competizioni con precisione del millesimo di secondo, ho abilitato delle ISR con i pin esterni di arduino 2 e 3 per avere la migliore reattivita' possibile, il problema e' che non so se dato dal display i2c o da altri fattori, ma credo che con le operazioni sul display il millis() si interrompa per brevissimi periodi di tempo ogni volta che scrivo sul display (ogni 400ms di delay) e questo in un limite tempo di 10 minuti mi porta ad avere uno scarto di circa due/tre decimi di secondo quindi di 300 ms su 600000 ms (10 minuti), ho letto che arduino ha tre timer, e' possibile rendere un timer indipendente da qualunque tipo di evento esterno o di interrupt e usarlo solo in lettura?
perche' in caso predispongo un timer solo per questo e risolvo il problema, seconda cosa, la temperatura e le condizioni esterne quanto possono influenzare il clock dell'arduino? temperatura ecc... se queste condizioni esterne rendono il clock troppo instabile sarebbe possibile mettere un clock esterno ancora piu' preciso e utilizzarlo magari solo per un timer?
Ci sono varie domande a cui rispondere spero di essere stato abbastanza chiaro :)

gpb01

I timer sono indipendenti dagli interrupts ... è millis() che, ovviamente, si ferma se un altra ISR entra in funzione.

La soluzione è utilizzare un qualsiasi timer e leggere direttamente i suoi registri senza passare per le funzioni di Arduino (che poi è quello che fa la funzione micros() che, difatti, funziona anche dentro una ISR).

Guglielmo
Search is Your friend ... or I am Your enemy !

Ketto


Claudio_FF

#3
Sep 23, 2019, 10:25 pm Last Edit: Sep 23, 2019, 10:30 pm by Claudio_FF
la temperatura e le condizioni esterne quanto possono influenzare il clock dell'arduino? temperatura ecc...
Su un "Arduino standard" con oscillatore a risuonatore ceramico normalmente contare il tempo con millis/micros ha un errore di circa 5..10 secondi all'ora.

Si può però montare un "Arduino standalone" con oscillatore al quarzo (o trovare un vecchio Arduino2009) e i tempi migliorano sensibilmente.
********* IF e SWITCH non sono cicli ! *********
**** Una domanda ben posta è già mezza risposta ****
*** La corrente si misura in mA, la quantità di carica in mAh ***

Maurotec

Quote
ah.  :smiley-eek:
Che sia chiaro non è colpa di millis() ma in generale un evento scatenato da un timer hardware come ad es. overflow di TCNT0 può essere collegato ad una ISR la quale contiene del codice che richiede del tempo per essere eseguita.

Se nella mia ISR che fa altro ed è collegata ad altri eventi io ci metto del codice che impegna la CPU per un minuto, l'altra ISR legata al timer non verrà eseguita per almeno un minuto.

Si dice appunto che le ISR sono task non interrompibili.
Questo comportamento è modificabile, cioè si possono configurare le ISR per essere interrompibili da altri eventi ma la gestione a me non è mai riuscita per niente bene, comunque a te non serve.

Ti basta una ISR legata ad uno dei timer che scatti quando il contatore va in overflow e ci deve andare ogni 1ms.
Poi gestione e visualizzazione non devono usare ISR, quindi niente buffer ring della seriale, quindi ciao ciao serial.println ecc.

Per l'altra domanda circa il clock c'è la possibilità di fare viaggiare il 328 con l'oscillatore RC interno e collegare un quarzo agganciato ad un timer (non ricordo bene quale timer e comunque c'è da studiare il datasheet). Oppure da uno dei pin XTAL si collega una fonte di clock esterna e la MCU viaggia a quella velocità senza quarzo.

Le sorgenti di clock esterne esistono sotto forma di strumentazione o di chip, per le sigle e prezzi occorre spulciare i siti dei produttori, sicuramente Microchip ha qualcosa a catalogo. 

Ciao.

Ketto

ho fatto un esperimento ieri sera e ho preso due arduini mega (uno della sunfounder e uno della keyestudio) e un arduino nano sempre clone, li ho collegati in parallelo ad un unico sensore touch e li ho fatti quindi partire e fermare tutti e 3 nello stesso momento (stesso sketch in ognuno) per vedere quanta differenza c'era tra di loro, nonostante siano a 16 mhz dichiarati l'arduino della sunfounder e' il piu' preciso e si discosta di tipo 1 decimo di secondo su 10 minuti, a questo punto credo che il problema oltre le isr sia anche la bonta' del clock, di conseguenza se trovassi tipo un quarzo qualitativamente buono e lo sostituissi alla scheda il risultato potrebbe migliorare gia' solo cosi?
inoltre se a prescindere so di quanto un quarzo e' sballato rispetto alla sua dichiarazione di fabbrica non posso fare tipo una proporzione e sistemare manualmente il risultato? cioe' tipo che ne so, so che ogni 10 minuti il millis e' avanti di 4 centesimi di secondo, se facessi una proporzione e vedessi che percentuale di errore c'e', non potrei semplicemente aggiungere o togliere questa percentuale al risultato finale in modo da correggerlo? se su 10 minuti sbaglia di 4 centesimi, su 5 minuti ne sbagliera' di 2, no? la cosa che mi turba e' che i quarzi soffrono l'eta e' non so se a' distanza di tempo l'errore sara' lo stesso o meno.

speedyant

Se i "tempi" sono cosi importanti, io opterei per un modulo gps e un modulo rtc, sommato ad una shield lan per la gestione di un ntp server remoto.

Maurotec

Quote
del clock, di conseguenza se trovassi tipo un quarzo qualitativamente buono e lo sostituissi alla scheda il risultato potrebbe migliorare gia' solo cosi?
Non si tratta di sostituire un quarzo con un altro più preciso, infatti la precisione la puoi ottenere tarando il circuito di contorno al quarzo, curando il layout e variando il valore dei condensatori. Però la precisione così raggiunta non ci assicura stabilità a variare delle condizioni a contorno. Avendo a disposizione della strumentazione affidabile e certificata possiamo procedere a rendere preciso il clock, poi dobbiamo variare le condizioni a contorno, ad esempio la temperatura passa da 25°C a 35°C e osserviamo di quanto slitta il clock (io suppongo che la frequenza diminuisce all'aumentare della temperatura) e se lo slittamento è lineare in relazione alla temperatura oppure se è una curva.

Ottenute più informazioni possibili si cerca un modo per compensare lo slittamento. Tutto sto sbattimento per un amatore lo trovo eccessivo a fini pratici, ottimo invece dal punto di vista della didattica. A questo punto si cerca una fonte di clock in chip compensata in temperatura e la si fornisce alla MCU, da qui in poi ci si può concentrare sul codice.

https://it.wikipedia.org/wiki/Oscillatore_termocompensato   

Ciao.

speedyant

Anche secondo me per uso "amatoriale" queste preoccupazioni sullo scarto in frequenza mi sembrano eccessive.

Ketto

#9
Sep 24, 2019, 05:59 pm Last Edit: Sep 24, 2019, 06:19 pm by Ketto
purtroppo il tempo anche se un progetto amatoriale mi serve preciso al centesimo almeno... quindi ovviamente se il quarzo rompe le scatole dando oscillazioni gratis in piu' non va bene
ho provato con l'rtc (non pensavo potesse generare segnali ad onda quadra) ma ha quattro frequenze fisse che sono 1 1024 4096 e 8192 Hz.
se io volessi cercare di ottenere una frequenza di 1KHz precisa, c'e' un qualche modo anche tramite software prescaler che caspita ne so... oppure nada?

comunque io a questo punto direi di tararli manualmente e buonanotte, vedo che scarto c'e' se per eccesso o difetto lo correggo e li faccio precisi, credo che sia il metodo migliore

Maurotec

Quote
ma ha quattro frequenze fisse che sono 1 1024 4096 e 8192 Hz.
Ok, ma la sigla di questo RTC qual'è?

Tutti i tre timer possono ricevere una sorgente di clock esterna, i pin T0, T1 e T2 per rispettivi timer.
Per configurare i timer si agisce su i primi tre bit del registro TCCRnB, dove 'n' identifica il timer 0, 1 e 2.

Il timer 1 ha risoluzione di 16-bit, gli altri due 8-bit.

T=1/F = 1/11024=0,000090711s.
T è il periodo, cioè due fronti di salita distano T, come pure due fronti di discesa distano T. 

0,000090711s sono 0,090711176ms, 90,711175617us.

1000us == 1ms, quindi 1000 / 90,711175617us=11,024 conteggi del timer TCNTn, TCNTn è un registro interno di 16-bit.
quindi non può rappresentare la virgola, per cui 11,024 si arrotonda a 11.

11 conteggi x 90,711175617us = 997,822931787us.

Per adesso mi fermo qui, anzi no l'oscillatore RC interno può essere tarato, cioè lo puoi accelerare o decelleraere.

Ciao.

Ketto

madonna quanto sono belli i timer, comunque e' il ds3231, ora ci smanetto un poco, vediamo che riesco a fare, grazie mille comunque mi state facendo imparare un botto di cose, con altro studio vorrei incollarle tutte assieme <3

gpb01

#12
Sep 24, 2019, 10:19 pm Last Edit: Sep 24, 2019, 10:19 pm by gpb01
>Ketto: scusa, ma la precisione che richiedi, su che durata ti occorre?  Ovvero, devi misurare centesimi di secondo su un periodo di ? ? ? secondi? minuti? ore?

Guglielmo
Search is Your friend ... or I am Your enemy !

Maurotec

Quote
comunque e' il ds3231
Ok è già termo compensato quindi hai già un sorgente di clock abbastanza precisa e stabile nel tempo.

C'è un errore nel calcolo che ho fatto, cioè quanto TCNTn vale 3 hai accumulato 90,711175617us x 2, quindi OCRnA deve essere impostato a 12, quando anche TCNTn vale 12 avviene il salto alla ISR TIMERn_COMPA (o come si chiama per il 328). Nella ISR dovrai azzerare TCNTn e  incrementare di una unità il contatore di millesimi di secondo.

Variante che aumenta raddoppia la velocità con cui conta il timer: Nella ISR inverti lo stato del bit 0 (CS10) del registro TCCRnB, così il contatore viene incrementato su rising che falling edge.

PS:mmmh c'è errore o no? Verifica sempre non fidarti.

C'è un'altra possibilità che senza avere verificato credo sia più ingarbugliata e quindi l'ho scartata. Il timer1 ha la funzione ICP (Input Capture Unit) grazie alla quale si può tarare l'oscillatore RC interno.

Ciao.

Ketto

per quanto riguarda la durata, come scritto sopra, e' di massimo 10 minuti, quindi la precisione comunque non mi serve per un tempo infinito, pero' in 10 minuti diciamo di si.
Per quanto riguarda l'errore del ds3231 ho verificato collegandolo all'interrupt 2 e aumentando su rising la variabile, su un clock di 1024 mi sfasa di circa due impulsi per secondo..
Per quanto riguarda la taratura dell'oscillatore, invece, stai dicendo che e' possibile tramite pin esterno tarare la frequenza e magari correggerla?

Go Up