Edoardo Vignali
Libreria Metro e gestione di intervalli di tempo senza delay
Tutorials -
Mercoledì 04 Agosto 2010 09:14
Scritto da Edoardo Vignali

Utilizzare la libreria metro al posto dei semplici delay può aiutare a massimizzare le potenzialità del nostro microcontrollore, infatti un delay in linguaggio "arduino C" non è altro che un NOP in assembler. L'istruzione NOP in assembler non fa fare nulla al nostro microcontrollore per un ciclo macchina, quindi con un quarzo a 16MHz il ciclo macchina durerà 62.5nS.

Durante il NOP non vengono eseguite istruzioni dal "cervello" del nostro microcontrollore però tutti i bit che arrivano sul pin RX per una comunicazione seriale vengono registrati, gli interrupt continuano ad essere gestiti come lo erano prima e di conseguenza anche il PWM continuerà a funzionare, ma questo a livello harware. A livello software il nostro microcontrollore si congela per la durata del delay e specialmente in applicazioni che richiedono molti calcoli, noi non vorremmo mai che il nostro microcontrollore aspettasse un tot di tempo senza fare nulla.

Per gestire la temporizzazione di eventi senza usare il delay possiamo agire in due modi, usare la libreria metro oppure usare la funzione Millis();.

Libreria Metro

La libreria Metro è particolarmente indicata per applicazioni di blinking di led, controllo di servomotori e comunicazioni seriali. Adesso vi spiegherò come creare e gestire un'istanza per questa libreria. Questa libreria non viene gestita a interrupts quindi è bene fare un controllo ponderato sul nostro intervallo e verificare che non sia scaduto.

Metodi della libreria Metro

  • Metro(unsigned long interval);

Crea l'oggetto metro e gli assegna un intervallo in mS

  • Metro(unsigned long interval, byte autoreset);

Crea l'oggetto metro assegnandogli un intervallo in ms. Con autoreset settato a TRUE il contatore si resetta ogni qual volta scada l'intervallo di tempo precedentemente settato.

  • byte check();

Restituisce TRUE una volta trascorso l'intervallo settato in precedenza, restituisce FALSE se l'intervallo non è scaduto.

void interval(unsigned long interval);

Assegna un nuovo intervallo.

  • Void reset();

resetta il timer

Eccovi degli esempi: Ecco come far Lampeggiare un led usando la libreria metro

Includete la libreria metro

#define LED 13 // Il pin a cui è collegato un led direttamente sulla scheda Arduino

//Crea una variabile di stato
int state = HIGH;

// Istanzia un oggetto Metro definendo un intervallo di 250mS
Metro ledMetro = Metro(250); 

void setup()
{
  pinMode(LED,OUTPUT);
  digitalWrite(LED,state);
}

void loop()
{

  if (ledMetro.check() == 1) { // Si controlla che l'intervallo sia scaduto
    if (state==HIGH)  { 
      state=LOW;
      ledMetro.interval(250); //Se il pin è HIGH reimposta l'intervallo a 250mS
    } 
    else {
      ledMetro.interval(1000); // Se il pin è LOW si reimposta l'intervallo ad 1s
      state=HIGH;
    }
    digitalWrite(LED,state);
  }
}

Millis(); e Micros();

Queste due funzioni restituiscono rispettivamente il tempo in millisecondi e in microsecondi da quando il nostro arduino ha iniziato a far girare il programma corrente. Non è semplice spiegare a parole come utilizzare queste due istruzioni, spero che capiate con questo semplice esempio. Collegate un bottone di tipo booleano al pin 2 con una resistenza di pill up da 1kohm.

Arduino debounce

const int ledPin =  13;      // definizione del pin associato al led

int ledState = HIGH;         // stato iniziale di questo pin
int buttonState;             // variabile in cui sarà scritta lo stato attuale del bottone
int lastButtonState = LOW;   // variabile che conterrà la lettura precedente del bottone

// Queste variabili vanno dichiarate long perchè diventeranno molto grandi
long lastDebounceTime = 0;  // L'ultima lettura di millis(); in cui il bottone è stato premuto
long debounceDelay = 50;    // Definizione del tempo di debounce (rimbalzo)

void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // legge lo stato del bottone e lo mette in una variabile locale
  int reading = digitalRead(buttonPin);

   // se lo stato del bottone è cambiato a causa di una pressione 
   // o di rumore
  if (reading != lastButtonState) {
    // si resetta il timer 
    lastDebounceTime = millis();
  } 
  
  if ((millis() - lastDebounceTime) > debounceDelay) {
    // qualsiasi sia il valore della lettura, se la differenza tra il tempo attuale
    // e il valore di tempo acquisito quando è cambiato lo stato è maggiore
    // del tempo di debounce allora si acquisisce la lettura.
    buttonState = reading;
  }
  
  // impostiamo il led usando la variabile buttonState
  digitalWrite(ledPin, buttonState);

  // Salviamo la lettura del bottone. Nel prossimo loop
  // la lettura del bottone verrà comparata con questo valore.
  lastButtonState = reading;
}

Liberamente tratto dal playground inglese di arduino

CC

 

Gioblu Robotics © 2010 - 2012 · Sitemap · privacy

gioscarab@gmail.com

Gioblu BOTServer è online dal 10 Aprile 2010 - 319.232 Visite - 1.027.175 Pagine visualizzate - 182.309 Visitatori unici - 536 utenti attivi