INPUT/OUTPUT DIGITALE: Esempio PUSHBUTTON+LED

Costruire il seguente circuito (serve una resistenza da 10K, un diodo led e un pulsante o pushbutton)

Ricordate di collegare il catodo del diodo LED su GND e l’anodo all’uscita digitale 13. Ecco l'immagine del circuito

Codice Sorgente A

/* -----------------------------------------------------------------------------------
 Esempio creato partendo dal codice presente sul sito: www.maffucci.it.
 Scopo del programma è accendere un led quando il pulsante è premuto 
----------------------------------------------------------------------------------- */
#define LED 13                // LED collegato al pin digitale 13  
#define BOTTONE 7             // pin di input dove è collegato il pulsante  
int  val = 0;                 // variabile usata per conservare lo stato del pin BOTTONE  
  
void setup() 
{  
  pinMode(LED, OUTPUT);       // imposta il pin digitale come output  
  pinMode(BOTTONE, INPUT);    // imposta il pin digitale come input  
}  
  
void loop() 
{  
  val = digitalRead(BOTTONE);  // 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  
}
Come potete constatare oltre all’istruzione digitalRead() in grado di leggere lo stato di un sensore esterno (bottone) abbiamo anche l’istruzione if…else. L’istruzione if…else consente di prendere delle decisioni in funzione del fatto che una determinata condizione logica sia VERA o FALSA. Nel caso in cui la condizione sia VERA viene eseguito il primo blocco di istruzioni, nel caso in cui la condizione sia FALSA, viene eseguito il secondo blocco di memoria. La condizione logica è espressa tra parentesi tonde subito dopo la parola if. Tornando al codice del programma “Esempio 1″ notate che ho usato “==” invece di “=” per confrontare i due elementi

Codice Sorgente B

Lo scopo di questa versione di programma è quello di realizzare un circuito simile a quello di un impianto di illuminazione: “premo il pulsante accendo la luce, premo una seconda volta e spengo la luce”. Nel precedente programma non dobbiamo mantenere il dito sul pulsante per mantenere acceso il led!

Vediamo questa prima versione (provvisoria):

/* -----------------------------------------------------------------------------------
 Esempio creato partendo dal codice presente sul sito: www.maffucci.it.
 Scopo del programma è accendere o spegnere un led (a seconda del suo stato) quando
 premo il pulsante 
----------------------------------------------------------------------------------- */
#define LED 13        // LED collegato al pin digitale 13  
#define BOTTONE 7     // pin di input collegato al pulsante  
int val = 0;          // val conserva lo stato attuale del pin di input (7) 
bool accendi;         // Accendi = true  => devo accendere il LED 

void setup() 
{  
  pinMode(LED, OUTPUT);       // imposta il pin digitale (13) come output  
  pinMode(BOTTONE, INPUT);    // imposta il pin digitale (7) come input  
  digitalWrite(LED, LOW);     // spegne inizialmente il led
  accendi = false;
}  
  
void loop() 
{  
  val = digitalRead(BOTTONE);  // legge il valore dell'input e lo conserva  
  
  // controllo se lo stato del pulsante sia diventato "premuto" (lo stato 
  // cambia anche quando rilascio il bottone!)
  if (val == HIGH)      // Se premuto ...
    accendi = !accendi; // cambio lo stato  
  
  if (accendi)  
    digitalWrite(LED, HIGH);  // accende il led  
  else
    digitalWrite(LED, LOW);   //spegne il led 
  // se metto delay(100); noterò uno sfarfallio nel led che evidenzia
  // i continui cambi di stato 
}

Se proviamo il programma notiamo un funzionamento molto strano. A seconda del tempo di pressione del pulsante potrebbe capitare che il led non si accenda o si spenga correttamente. Ad esempio: se il led è acceso, premendo il pulsante, questo non si spegne.

Ciò è dovuto al fatto che Arduino legge le istruzioni del programma ad una velocità molto elevata (milioni di istruzioni al secondo). La pressione del pulsante, per quanto possiamo essere veloci, sarà di durata nettamente superiore all'intervallo di esecuzione di arduino. Questo implica che la condizione val==HIGH sia vera per tutta la durata della pressione e quindi lo stato del led passerà da HIGH a LOW in continuazione (possiamo accorgerci di questo continuo cambio di stato se mettiamo in fondo al programma un'istruzione delay(100)!). Non ci accorgiamo di questo continuo cambio di stato poiché il led continua ad emettere luce anche dopo essere stato posto a OFF per un periodo breve ma comunque superiore alla frequenza di esecuzione di arduino: noteremo solo un lieve abbassamento della luminosità. Quando rilasciamo il pulsante la variabile "accendi" avrà quindi un valore imprevedibile (dipende da quante volte ha cambiato di stato nell'intervallo di pressione del pulsante!).

Per evitare questo continuo ON/OFF del led basta semplicemente memorizzare lo stato del pulsante nel loop() precedente. Solo al primo cambio di stato del bottone effettuo l'accensione/spegnimento del LED. I successivi loop, caratterizzati dal medesimo stato del pulsante, verranno ignorati mediante l'istruzione di uscita return;

Vediamo quindi la versione corretta:

/* -----------------------------------------------------------------------------------
 Esempio creato partendo dal codice presente sul sito: www.maffucci.it.
 Scopo del programma è accendere o spegnere un led (a seconda del suo stato) quando
 premo il pulsante 
----------------------------------------------------------------------------------- */
#define LED 13        // LED collegato al pin digitale 13  
#define BOTTONE 7     // pin di input collegato al pulsante  
int val = 0;          // val conserva lo stato attuale del pin di input (7) 
int prec_val;         // Variabile per valutare lo stato del precedente Loop
bool accendi;         // Accendi = true  => devo accendere il LED 
  
void setup() 
{  
  pinMode(LED, OUTPUT);       // imposta il pin digitale (13) come output  
  pinMode(BOTTONE, INPUT);    // imposta il pin digitale (7) come input  
  digitalWrite(LED, LOW);     // spegne inizialmente il led
  accendi = false;
}  
  
void loop() 
{  
  val = digitalRead(BOTTONE);  // leggo il valore dell'input e lo conservo in val  
  if (val==prec_val) return;   // Se lo stato del bottone è invariato (esempio continuo a 
                               // premere il pulsante) non faccio nulla ed esco dal loop
  prec_val=val;                // salvo lo stato come precedente per la prossima esecuzione di loop()
  
  // controllo se lo stato del pulsante sia diventato "premuto" (lo stato cambia anche quando
  // rilascio il bottone!)
  if (val == HIGH)       // se premuto ...
     accendi = !accendi; // cambio lo stato  
  
  if (accendi)  
    digitalWrite(LED, HIGH);   // accende il led  
  else
    digitalWrite(LED, LOW);    // spegne il led  
}