Tinkercad Delay2Millis affronta uno dei temi che più spesso mi viene richiesto nei commenti e nei corsi.
No, non è la domanda classica “che differenza c’è tra i comandi delay() e millis() ?” per la risposta ti rimando ad uno dei miei primi articoli su questo blog: Tutorial: millis() contro delay().
La richiesta che spesso ricevo è:
” come posso sostiture il comando delay() con il comando millis() ? “
ho quindi deciso di fare qualche test usando Tinkercad per testare questa possibilità.
Notice
Di esempi che ti spiegano come sostiture il primo con il seocndo comando ne trovi moltissimi online.
Il test che realizzerai con questo esempio è creare una funzione che al pari di delay() puoi richiamare direttamente.
Per l’esempio usi il classico Blink in una versione rivisitata che al posto del solo comando delay( 1000 ) userà una funzione che ho chiamato delay2millis() il cui scopo è controllare lo scorrere del tempo restituendo alla loop() un return code ad ogni esecuzione.
In questo modo potrai tener sotto controllo l’esecuzione dello sketch.
Prima di analizzare il codice inizia con il video che ho realizzato per questo tutorial tinkercad.
Il video Tinkercad Delay2Millis
nel video che vedi di seguito, dedicato al Tinkercad Delay2Millis, vedi come è stato scritto lo sketch che analizzeremo nel prossimo paragrafo:
come hai visto ho utilizzato il classico esempio blink per testare la possibilità di usare il comando millis() al posto del comando delay();
Salto la descrizione del circuito che avrai visto essere davvero semplicissimo:
Analizziamo insieme il codice scritto per questo test.
Sketch del delay2millis
lo sketch del tinkercad Delay2Millis che trovi anche sul progetto condiviso ( link al progetto tinkercad ) e che ti riporto di seguito:
unsigned long interval=500; unsigned long prevTime=0; boolean delay2Millis ( int multiplier=0 ) { boolean retCode=1; Serial.print( millis() ); Serial.print( " - " ); Serial.print( prevTime ); if ( millis() - prevTime > ( interval * multiplier ) ) retCode=0; Serial.print( " - " ); Serial.print( retCode ); Serial.println(); return retCode; } void setup() { Serial.begin( 115200 ); pinMode(3, OUTPUT); digitalWrite( 3,0 ); } void lightOn() { Serial.print( "Light on - " ); digitalWrite( 3,1 ); delay( 100 ); } void lightOff() { Serial.print( "Light off - " ); digitalWrite( 3,0 ); delay( 100 ); } void loop() { prevTime=millis(); while( delay2Millis(4) ) lightOn(); prevTime=millis(); while( delay2Millis(2) ) lightOff(); }
in cui noti subito che nelle prime linee sono definite due variabili:
- interval: definisce un intervallo di attesa base su cui applicherai un moltiplicatore per ottenere il tempo di attesa definitivo;
- prevTime: serve a memorizzare il tempo trascorso;
dalla linea 04 alla linea 18 definisci la funzione delay2Millis() che userai per valutare il tempo trascorso.
Questa funzione ha il compito di controllare quanto tempo è trascorso dalla prima volta che viene chiamata e valuta se è trascorso l’intervallo di tempo moltiplicato il valore di moltiplicazione impostato.
ogni volta che richiami la funzione delay2Millis viene confrontato il tempo trascorso e restituito un valore che sarà 0 o 1 in funzione del tempo trascorso: 0 se è stato superato il tempo impostato e 1 se il tempo trascorso è inferiore all’intervallo impostato.
la linea 05: imposti la variabile retCode a 1;
le linee 07-09: servono solo a scriverti sul monitor seriale il tempo che scorre e il tempo da cui i check sono partiti;
la linea 11: è quella che si preoccupa di verificare il tempo che passa e ritorna 0 se tale tempo è superiore all’intervallo specificato;
le linee 13-15: come le precedenti 07-09 ti servono per visualizzare sul Monitor Seriale il valore di retCode che sarà restituito;
linea 17: restituisce il retCode calcolato in questa funzione;
dalla linea 20: inizia la funzione setup();
linea 22: imposti la velocità di comunicazione verso il monitor seriale;
le due linee 23-24: impostano il pin 3 in modalità OUTPUT e inviano un segnale digitale a 0;
le linee 27-31 e 33-37: sono le due funzioni che di occupano di accendere o di spegnere il led connesso al pin 3;
per ciascuna funzione trovi alla fine un delay di 100ms che è circa 1/5 dell’intervallo base, tale valore è impostato a titolo didattico ed di esempio e puoi variarlo in base alle esigenze del tuo sketch;
La funzione loop()
la funzione loop() è come sempre il cuore pulsante dello sketch.
Vogliamo che il controllo dello sketch resti sempre in questa funzione e da qui parta l’esecuzione di ogni funzione successiva;
la linea 41: imposta il valore di prevTime uguale al millisecondo corrente: millis() al momento in cui la linea verrà eseguita;
linea 42: imposta un ciclo di tipo while basato sul return code proveniente dalla funzione delay2Millis() a cui passi come valore di moltiplicazione dell’intervallo “4” ossia 500 x 4 = 2000 ms = 2s;
ciascun ciclo del while chiama la funzione lightOn() che provvede ad accendere il verde;
linea 43: si comporta come la linea 41;
linea 44: è simile alla linea 42 ma con valore di moltiplicazione 2 e richiamando la funzione lightOff(); il fattore di moltiplicazione 2 che comporta 500 x 2 = 1000ms = 1s.