mercoledì 1 gennaio 2014

Interrupt su Arduino

Supponiamo il seguente scenario con protagonista un microcontrollore Arduino
1) Il compito e' quello di effettuare un compito ripetitivo (perfetto per il loop) ma di lunga durata.
2) All'interno di questo compito di lunga durata devono essere intercettati eventi (quale puo' essere un sistema di allarme od un sistema di protezione) in realtime che forzi Arduino ad agire immediatamente

Questo e' un campo di applicazione degli interrupt

Per semplificare diciamo che il compito ripetitivo e' quello di far blinkare il led in porta D13 con un ciclo di 10 secondi mentre l'evento extra e' dato dalla pressione di un pulsante collegato al pin D02 (interrupt 0 su Arduino UNO) che accenda il led in porta D12


Nel video si osserva come nel caso di accensione del led non determinato dall'interrupt si deve attendere che il loop effettui il suo ciclo completo (vedi sorgente sottostante, un ciclo completo e' di 10 secondi), nella seconda parte gestita dall'interrupt l'accensione e' istantanea

Come e' fatto il circuito



L'aspetto importante di questo esempio e' la possibilita' di effettuare operazioni all'interno di un interrupt (l'esempio del sito di Arduino mostra come cambiare il valore di una variabile ma l'azione di interpretare la variabile ed agire di conseguenza era sempre demandata al loop, cosi' se questo era occupato in una operazione lunga, non c'e' nessun vantaggio)


con gestione interrupt
-----------------------------------------------
int pin = 13;
volatile int state = LOW;
int led = 12;



void setup()
{
  pinMode(pin, OUTPUT);
  pinMode(led, OUTPUT);  

  attachInterrupt(0, blink, CHANGE);
}

void loop()
{
  digitalWrite(led, HIGH);  
  delay(1000);               
  digitalWrite(led, LOW);    
  delay(1000);               
}

void blink()
{
  state = !state;
  digitalWrite(pin, state);

}
-------------------------------------------------------------------------


senza gestione interrupt
-------------------------------------------------------------------------
#define led 13               
#define led2 12
#define BUTTON 2           
int  val = 0;                 

void setup() {
  pinMode(led, OUTPUT);       
  pinMode(BUTTON, INPUT);     
  pinMode(led2, OUTPUT);
}

void loop() {
  val = digitalRead(BUTTON);  // legge il valore dell'input e lo conserva

  // controlla che l'input sia HIGH (pulsante premuto)
  if (val == HIGH) {
    digitalWrite(led, HIGH);  //accende il led
  }
  else {
    digitalWrite(led, LOW);   //spegne il led
  }
  digitalWrite(led2, HIGH);   
  delay(5000);               
  digitalWrite(led2, LOW);    
  delay(5000);           
}