Cronometro ad alta precisione

Salve a tutti!
Sto cercando di progettare un cronometro millesimale, via software. So che per aumentare la precisione sarebbe meglio farlo hardware e mantenere la temperatura dell’oscillatore costante, ma per il momento cerco di focalizzarmi sul programma e sto riscontrando un problema e volevo chiedervi un informazione:
esiste qualche metodo o funzione per sapere con esattezza quanto tempo mette Arduino a svolgere un blocco di istruzione? Ho provato stampando nel monitor seriale ma da quest’ultimo risulta che vengono fatte nello stesso millisecondo le istruzioni, poi, dopo diversi millisecondi Arduino rifà le istruzioni per tre volte nello stesso millisecondo e così via.
Volevo anche chiedervi se esiste una funzione per contare i microsecondi a partire dal valore di una variabile e non dall’inizio del programma?
Inoltre, a me non risulti che in Arduino sia presente un orologio hardware, ma qualora fosse il caso, esiste una funzione per recuperarne l’ora esatta (al millesimo)?
Non so se mi sono spiegato bene...
Grazie in anticipo e buona serata!

Guarda qui dovrebbe fare al caso tuo.
Per gestire la differenza di tempo ti puoi comportare esattamente come si fa con millis() ovvero memorizzi l'istante che ti interessa, fai ciò che devi, sotrrai l'attuale valore al tuo t iniziale e hai i microsecondi trascorsi per eseguire un certo blocco di operazioni

Con la funzione 'micros' leggi un contatore interno espresso in microsecondi con un errore di 4µs. Il normale oscillatore ceramico presente su ArduinoUNO originale ha però un errore di circa cinque secondi all'ora (1,39ms al secondo).

Nel momento da cui intendi partire con la misura salvi in una variabile uint32_t il valore ritornato da micros.
Dopo di che il tempo trascorso (in microsecondi) è dato da

micros()-variabile

Un Arduino con oscillatore quarzato sarebbe decisamente più preciso (ad esempio uno standalone o alcuni cloni).

In alternativa una sorgente esterna, come l'onda quadra 1024Hz prodotta da un RTC DS3131, che ha un errore di qualche secondo al mese [1]

[1] Dubbio: sarà l'oscillatore compensato in temperatura ad essere così preciso, oppure la compensazione avviene a livello software tenendo conto dell'errore dell'oscillatore?

Innanzitutto grazie mille per il vostro prezioso aiuto! Domani proverò a mettere in pratica i volti consigli e vi farò sapere

Buon pomeriggio a tutti!
Mi sono informato parecchio e mi sono accorto che usare la funzione delay(1); per il mio progetto è sbagliato in quanto quest’ultima ferma il programma per un millisecondo, ma non prende in considerazione il tempo che è già stato impiegato per svolgere le istruzioni avvenute prima. Il problema è che quindi il programma non va a conteggiare 1 millisecondo ma ben di più.
Cercando in rete mi sono focalizzato su una possibile soluzione: i timer interni ad Arduino. So che ci sono molto tutorial online ma non capisco come utilizzare i timer all’interno del mio programma...
Qualcuno potrebbe aiutarmi nell’implementazione di questi ultimi all’interno del mio progetto?
Grazie in anticipo a tutti.

Hai a disposizione due funzioni che, già di base, ti ritornano il valore di due contatori (gestiti tramire un timer) indipendenti dall'esecuzione del programma ...

millis(): ti ritorna il valore di un contatore che viene incrementato automaticamente ogni millisecondo. La rappresentazione è a 32bit il che significa che, circa ogni 49 giorni, va in overflow e ricomincia da zero.

micros(): anche essa ti ritorna il valore di un contatore che viene incrementato automaticamente e la sua precisione è di +/- 4µsec. La sua rappresentazione è sempre a 32 bit il che significa che, circa ogni 70 minuti, va in overflow e ricomincia da zero.

All'occorrenza, entrambi gli oveflow sono molto facilmente gestibili come più volte spiegato su questo forum.

Guglielmo

Grazie!
Ho fatto come hai detto e in effetti la precisione sembra essere aumentata notevolmente!

i timer interni ad Arduino. So che ci sono molto tutorial online ma non capisco come utilizzare i timer all'interno del mio programma...

Se per tiimer interni intendi i timer hardware T0, T1 e T2, T0 è già usato da arduino per millis() e micros(), rimangono liberi T1 (16-bit) e T2 (8-bit). Per capire come sono usarli puoi aprire i file sorgente del core arduino (sono open sources) e studiarli. Di base ciò che si fa con T0 si fa con T1 ecc. Per capire come usarli devi documentarti su cosa sono le interruzioni (interrupts), chi li genera e cosa accade. Ogni timer ha necessità di una sorgente di clock, questa può passare per un prescaler (divisore) in modo da fare avanzare il conteggio più o meno rapidamente.

La bibbia sui timer (ma in generale) è il datasheet del microcontroller che trovi in formato pdf sul sito del produttore, es microchip. Nota che è richiesta una certa competenza generica per potere manipolare i registri del timer e non è per principianti, quindi procedi per gradi e non pretendere di arrivare alla soluzione ottimale in un paio di giorni.

Inoltre c'è sempre la deriva termica che non permette di raggiungere la precisione.

Ciao.

Onnwen:
Grazie!
Ho fatto come hai detto e in effetti la precisione sembra essere aumentata notevolmente!

Magari vedendo come hai fatto si può vedere se è solo un modo più preciso o se è IL più preciso.