Sempre più programmatori provetti hanno difficoltà ad usare la funzione millis(), forse perché non la comprendono.
Noi umani non siamo bravi a fare conteggi di tempo e questo si sa.
Se guardo l'orologio continuamente sto controllando in loop l'orario.
Su un foglio di carta, scrivo a matita il nome del timer che voglio controllare e accanto il valore.
myTimer =
Per me umano MyTimer = significa che ancora non ho preso il tempo di inizio, quindi posso considerare nullo o
zero MyTimer.
If (myTimer == 0)
myTimer = millis(); // equivale a leggere l'orario dall'orologio che ho al polso e scriverlo nel pezzo di carta.
Per cui nel pezzo di carta aggiorno il valore di myTimer:
myTimer = 10000 (diecimila)
Adesso myTimer non è più nullo o zero per cui myTimer = millis(); non viene più eseguito, e mi pare ovvio,
io prendo il tempo dal mio orologio una sola volta, ma sto sempre guardando l'orologio al polso.
L'orario scorre e millis() adesso restituisce un tempo maggiore a quello che ho scritto prima sul pezzo di carta.
La sottrazione di millis() - myTimer = ??. Il risultato dipende da quanto tempo è passato, supponiamo siano passati 1001 millesimi di secondo, quindi il calcolo millis() - myTimer = 1001.
Se io voglio compiere una azione ogni secondo, nel mentre che guardo l'orologio eseguo continuamente un controllo logico basato su un calcolo.
if ( ( millis() - myTimer ) > 1000)
; //eseguo l'azione perché sono passati più di 1000 millesimi di secondo (cioè 1 secondi)
Il calcolo (la sottrazione) lo eseguo prima della condizione logica > (magiore di), infatti notate le parentesi evidenziate:
( millis() - myTimer )
Supponiamo che la sottrazione l'abbia già eseguita:
if (1001 > 1000)
; eseguo l'azione.
Ci vuole un millesimo di secondo a valutare la condizione logica, basta uno sguardo e sappiamo che
1001 è maggiore di 1000 per cui il test è vero e quindi:
if (vero)
; eseguo l'azione.
Una delle prime cose da fare quando si esegue l'azione è quella di azzerare la variabile del timer, per cui
if ( (millis() - myTimer)) > 1000) { // uso le graffe per aprire un blocco di codice necessario quando ci sono più
istruzioni nel corpo della if.
myTimer = 0; Equivale a cancellare il valore dal pezzo di carta e al suo posto scriverci zero.
// qui scrivi il tuo codice corrispondente alla/e azione/i
}
Ricapitolando:
// Dichiaro una variabile di tipo unsigned long con nome a scelta, es. myTimer (usate il nome che preferite)
unsigned long myTimer; /* es. il timer usato per la tastiera (in questo caso è meglio cercare un nome migliore di
myTimer*/
#define MYTIMER_ELAPSED 1000
void loop() {
if (myTimer == 0) // è molto efficiente perché esiste una istruzione assembly equivalente a if (variabile == 0) salta
myTimer = millis(); // mi annoto il tempo nel pezzo di carta
// nota come non ho usato le graffe. Non servono e sono opzionali se c'è una solo istruzione nel blocco della if
// Sostanzialmente equivale a dire che il blocco implicito della if è grande una sola istruzione, se voglio
// estendere tale blocco devo usare le graffe {}.
if ( (millis() - myTimer) > MYTIMER_ELAPSED ) {
myTimer = 0; // azzero il mio timer
// qui scrivi il codice corrispondente alle azioni da intraprende. Nota l'uso delle graffe
}
}
Spero sia di aiuto a chi si confonde davanti a millis e finisce per usare delay, che può essere usato
con valori di pochi millesimi di secondo senza avere effetti disastrosi. Valori di delay accetabili vanno da 1 a
200, però se nel codice ci sono 20 delay(200) la cpu sta a contare per 4 secondi e allora conviene ricorrere a millis()
Ciao.