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 }