Semplice orologio con la funzione millis()
Scandire il tempo con Arduino per gestire azioni temporizzate
I microcontrollori, cuore delle schede Arduino, eseguono le varie operazioni basandosi su un Clock che scandisce il ritmo con il quale queste ultime vengono svolte. Il Clock può essere da un’oscillatore interno al microcontrollore stesso oppure esterno. Nel caso delle schede Arduino si sfrutta un oscillatore esterno 16 MHz.
Questo ha permesso di sviluppare un algoritmo che, con un margine piccolissimo di errore, ci permette di conoscere da quanti millisecondi il microcontrollore è stato alimentato. Tale informazione ci viene fornita dalla funziona Arduino millis().
L’informazione ottenuta deve essere gestita come un’informazione unsigned long e quindi il valore decimale massimo gestibile prima dell’overflow è 4 294 967 295 che corrisponde a (2^32 – 1). Tale valore, ricordiamo, è espresso in millisecondi. Quindi con dei semplici passaggi matematici possiamo affermare che tale variabile raggiungerà l’overflow prima di resettarsi dopo 49,71 giorni. Se il nostro progetto non prevede di rimanere attivo così a lungo il sistema sotto riportato andrà benissimo.
NB. Per funzioni avanzate della gestione del tempo è consigliabile adottare un modulo ausiliario RTC.
ESEMPIO
Funzionamento: quando il microcontrollore riceve il carattere ‘a’ via seriale (tale carattere corrisponde al valore decimale 97 nelle tabelle ashii) viene restituita l’informazione del tempo trascorso dall’avvio del microcontrollore .
Nella variabile tmp andremo a memorizzare il valore millis() riportato in secondi (basterà dividere per mille il valore ottenuto dalla funzione). Introduciamo anche due fattori correttivi (da impostare manualmente caso per caso prima di utilizzare tale metodo). Sfruttando una scheda Arduino UNO rev.3 ho notato che il microcontrollore ritarda il valore di millis() di 2 secondi ad ogni accensione/reset, e in seguito, ogni 10 minuti ritarda 1 secondo. Ecco quindi il motivo delle seguenti variabili che permetteranno di eliminare questi due errori sistematici:
- fattore_correttivo_tempo = 2 (incremento di Millis() all’avvio).
- fattore_correttivo_loop = 1 (valore incrementato alla variabile fattore_correttivo_tempo ogni 10 minuti).
// sistema di conteggio del tempo sfruttando clock di arduino // il programma restituisce quando riceve il carattere 'a' su seriale // l'informazione da quanti giorni, ore, minuti, secondi arduino è acceso unsigned long tmp; //variabile che contiene l'informazione millis()/1000 int secondi; // informazione dei secondi trascorsi dall'accensione int minuti = 0; // informazione dei minuti trascorsi dall'accensione int ore = 0; // informazione delle ore trascorse dall'accensione int giorni = 0; // informazione dei giorni trascorsi dall'accensione unsigned long variabile = 0; //variabile per la gestione della trasformazione da secondi a minuti //fattori correttivi tempo int fattore_correttivo_tempo = 2; //fattore correttivo iniziale +2 secondi, ogni 10 minuti verrà incrementato di fattore_correttivo_loop int fattore_correttivo_loop = 1; //fattore correttivo ogni 10 minuti +1 secondo void setup() { //attivo la comunicazione seriale Serial.begin(9600); } void loop() { tmp = (millis() / 1000); // prelevo il valore di millis() e lo trasformo in secondi secondi = tmp - (variabile * 10) + fattore_correttivo_tempo; // trasformo la variabile tmp in secondi da 0 a 60, applico fattore correttivo if (secondi > 60) { secondi = secondi - 60; // 60 secondi = 0, 61 secondi = 1 secondo, 62 secondi = 2 secondi... } // quando raggiungo 60 secondi incremento i minuti e aggiorno la variabile di trasformazione secondi minuti if (secondi == 60) { minuti = minuti + 1; variabile = variabile + 6; } //ogni 10 minuti, al secondo 1, incremento il fattore_correttivo_tempo di fattore_correttivo_loop if (((minuti == 10) || (minuti == 20) || (minuti == 30) || (minuti == 40) || (minuti == 50) || (minuti == 60)) && (secondi == 1)) { fattore_correttivo_tempo = fattore_correttivo_tempo + fattore_correttivo_loop; } //ogni 60 minuti incremento la variabile ora e azzero la variabile minuti if (minuti >= 60) { minuti = 0; ore = ore + 1; } //ogni 24 ore incremento la variabile giorni e azzero la variabile ore if (ore >= 24) { ore = 0; giorni = giorni + 1; } if (Serial.available() > 0) { if (Serial.read() == 97) { //se ricevo il carattere 'a' stampo a video le informazioni Serial.print(giorni); Serial.print(" giorni "); Serial.print(ore); Serial.print(" ore "); Serial.print(minuti); Serial.print(" minuti "); Serial.print(secondi); Serial.println(" secondi "); } } }