C'è una cosa importante che devi ricordare quando lavori con il tempo su un Arudino di qualsiasi forma:
- Ogni operazione richiede tempo.
La tua funzione foo () richiederà un certo tempo. Che cosa sia quel tempo, non possiamo dire.
Il modo più affidabile per gestire il tempo è fare affidamento solo sul tempo per l'attivazione, non per allenarsi quando dovrebbe essere l'attivazione successiva.
Ad esempio, prendi quanto segue:
if (millis() - last > interval) {
doSomething();
last = millis();
}
La variabile last
sarà il tempo di attivazione della routine * più il tempo doSomething
impiegato per l'esecuzione. Quindi diciamo interval
100, e doSomething
impiega 10ms per funzionare, otterrai trigger a 101ms, 212ms, 323ms, ecc. Non i 100ms che ti aspettavi.
Quindi una cosa che puoi fare è usare sempre lo stesso tempo a prescindere ricordandolo in un punto specifico (come suggerisce Juraj):
uint32_t time = millis();
if (time - last > interval) {
doSomething();
last = time;
}
Ora il tempo doSomething()
impiegato non avrà alcun effetto su nulla. Quindi otterrai trigger a 101ms, 202ms, 303ms, ecc. Ancora non esattamente i 100ms che volevi - perché stai cercando che siano passati più di 100ms - e questo significa 101ms o più. Invece dovresti usare >=
:
uint32_t time = millis();
if (time - last >= interval) {
doSomething();
last = time;
}
Ora, supponendo che non succeda nient'altro nel tuo loop ottieni trigger a 100ms, 200ms, 300ms, ecc. Ma nota quel bit: "fintanto che non succede nient'altro nel tuo loop" ...
Cosa succede se si verifica un'operazione che richiede 5ms a 99ms ...? Il prossimo trigger verrà ritardato fino a 104 ms. Questa è una deriva. Ma è facile combattere. Invece di dire "Il tempo registrato è ora" dici "Il tempo registrato è 100ms più tardi di quello che era". Ciò significa che, indipendentemente dai ritardi che si ottengono nel codice, l'attivazione sarà sempre a intervalli di 100 ms o alla deriva entro un segno di spunta di 100 ms.
if (millis() - last >= interval) {
doSomething();
last += interval;
}
Ora otterrai trigger a 100ms, 200ms, 300ms, ecc. O se ci sono ritardi in altri bit di codice potresti ottenere 100ms, 204ms, 300ms, 408ms, 503ms, 600ms, ecc. Cerca sempre di eseguirlo il più vicino possibile l'intervallo possibile indipendentemente dai ritardi. E se hai ritardi maggiori dell'intervallo, eseguirà automaticamente la tua routine abbastanza volte da tenere il passo con l'ora corrente.
Prima che tu fossi andato alla deriva . Ora hai jitter .