Go Down

Topic: precisione arduino (Read 3 times) previous topic - next topic

jacock

AHAHAHAAHAHHA, che mona... hai ragione..... scusa, ma sto facendo 7 robe contemporaneamente, e pensare risulta di troppo... :D

per snellire il codice invece? voi come lo avreste fatto?

astrobeed

#16
Aug 06, 2012, 10:32 pm Last Edit: Aug 06, 2012, 10:48 pm by astrobeed Reason: 1

Secondo me quello contribuisce non poco!


No, millis è gestito tramite un timer in free run e il relativo interrupt sull'overflow, puoi fare il codice complicato quanto ti pare, ma stai pur certo che ogni 1024 us, con un eventuale jitter di qualche us a seconda delle operazioni pendenti, c'è una interruzione per aggiornare millis.
Unico rischio di perdere dei count, citato anche da Massimo, è se nel tuo codice disattivi gli interrupt per un tempo maggiore di 1 ms, in questo caso è possibile perdere degli overflow del timer con relativo mancato aggiornamento del contatore, però è un caso limite in cui è difficile incappare a meno di non mettersi a pasticciare con gli interrupt senza sapere quello che si fa.

jacock

grazie 10000000000000000000000000000000

leo72


chissà se di questa particolarità ha tenuto conto Leo nel suo SWrtc (o RTCsw, ora non ricordo bene...)?

Come ha detto pablos, ne ho tenuto conto.
A seconda del clock, io uso un valore iniziale che assegno al contatore per far sì che l'overflow avvenga esattamente 1000 volte al secondo. Poi, come ha detto astrobeed, non è una formula esatta al 100% perché si verificano fluttuazioni stesse del risonatore/quarzo ma anche blocchi delle routine di reset per cui non si ottiene mai una precisione assoluta. Per sistemare un po', ho messo un deltaT, ossia una correzione da applicare sul calcolo dei secondi per far durare 1 secondo più o meno di 1000 ms, in modo da riavvicinare il conteggio del tempo al valore reale.

Tornando a millis, in realtà non è vero che il team di Arduino non ha previsto che il timer 0 va in overflow con un'accuratezza differente dalle 1000 volte al secondo. Anzi, mi permetto di contraddire astrobeed perché la formula da lui citata dà come risultato 976. Difatti per calcolare il tempo di 1 overflow si usa la formula
CLOCK/PRESCALER/RISOLUZIONE CONTATORE
Nel caso di Arduino, con clock a 16 MHz, prescaler a 64 e contatore ad 8 bit 8256), si ha
16000000/64/256=976.5625

La correttezza dei miei calcoli è provata anche dal fatto che il PWM usato dall'Arduino, Phase Correct PWM, dà come frequenza la metà del tempo di overflow, e difatti 976/2=488.28, che sono infatti i 490 MHz circa che citiamo sempre come frequenza del PWM.

Per ovviare a ciò, il team di Arduino introduce questo:
Code: [Select]
// the whole number of milliseconds per timer0 overflow
#define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000)

Questo correttore viene usato all'interno della ISR che intercetta l'overflow del timer 0 per "addirizzare" il conteggio: infatti non viene incrementato direttamente millis ma un contatore differente. 976/1000 dà 0.976, che è la durata dell'overflow sul timer 0 di Arduino Sommando 1024 volte 0.976 si arriva al valore corretto di 1000 overflow per secondo. Ed ecco che la correzione del timer settato incorrettamente porta ad un valore corretto (relativamente alla precisione del risonatore).

jacock

quindi non ho capito... devo mettere 1024 o 976??????

Go Up