Arduino

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 ");
    }
  }
}

MST-Admin

Appassionato di elettronica, elettrotecnica generale e programmazione. Fondatore del progetto MST-tutorial, desideroso di condividere con voi l'entusiasmo per l'innovazione tecnologica e la sperimentazione di novità tecniche in questi campi.

Articoli Correlati

Pulsante per tornare all'inizio