In una lezione precedente, ho cercato di spiegare cosa sono le macchine a stati, li facevo un esempio di come poterla utilizzare in Arduino.
L’esempio più semplice che mi è venuto è stato quello di cambiare lo stato di un led da spento ad acceso a lampeggiante, per poi tornare a spento.
Il led avrà quindi 3 stati:
stato 0: Led spento.
stato 1: Led acceso.
stato 2: Led lampeggiante (il classico blink).
Materiale Necessario
Se siete interessati al materiale, cliccate su questo e sarete indirizzati alla pagina Amazon
Ovviamente si possono aggiungere altri stati, ma per comodità mi fermerò a 3.
Prima di passare alla compilazione dello sketch, creiamo il nostro circuito, collegando un led con la sua resistenza ad Arduino.
Passiamo quindi alla compilazione dello sketch, come sempre riporto lo sketch per intero e poi lo analizzeremo parte per parte, una premessa io per il blink non userò il comando Delay, ma userò millis, così da non avere blocchi, durante il lampeggio, ma per avere uno sketch più piccolo inserirò un Delay antirimbalzo nella pressione del pulsante, per vedere come sostituire il Delay antiribalzo con millis, potete vedere il tutorial dedicato:
#8 Pulsante antirimbalzo con millis()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
/*HOBBYEIDDE switch case con led a tre stati hobbyeidee.altervista.org */ int stato = 0; unsigned long tempo, Dt = 0; int statoLed = LOW; void setup(){ pinMode ( 5, OUTPUT); pinMode ( 2, INPUT); } void loop(){ if(digitalRead(2)){ stato = stato+1; delay(300); } switch (stato){ case 0: digitalWrite(5, LOW); if(digitalRead(2)){ stato= stato+1; delay(300); } break; case 1: digitalWrite(5, HIGH); if(digitalRead(2)){ stato= stato+1; delay(300); } break; case 2: Dt = millis() -tempo; if( Dt >=500){ statoLed =! statoLed; digitalWrite( 5, statoLed); tempo= millis(); } if(digitalRead(2)){ stato= stato-2; delay(300); } break; } } |
Analizziamo lo sketch:
1 2 3 |
int stato = 0; unsigned long tempo, Dt = 0; int statoLed = LOW; |
Inseriamo quattro variabili:
- int stato dove memorizzeremo lo stato del pulsante.
- unsigned long tempo, in cui memorizzeremo il tempo trascorso.
- unsigned long Dt che sarà la differenza tra il tempo attuale ed il tempo trascorso dall’ultimo cambio di stato del pulsante.
- int statoLed che useremo per il blink, questa cambiare da LOW ad HIGH.
Sorvolo sul setup, in quanto è molto semplice, ho solo impostato il pin del led in uscita e quello del pulsante in entrata.
Passiamo al loop:
1 2 3 4 5 |
void loop(){ if(digitalRead(2)){ stato = stato+1; delay(300); } |
Partiamo con un if che gestisce il pulsante, questo if, funziona in maniera molto semplice, ad ogni pressione del pulsante incrementa di 1 il valore della variabile stato.
Adesso inizia la parte della cosiddetta macchina a stati:
1 2 3 4 5 6 7 8 |
switch (stato){ case 0: digitalWrite(5, LOW); if(digitalRead(2)){ stato= stato+1; delay(300); } break; |
la macchina inizia con uno switch collegato alla variabile stato, in pratica switch legge il valore della variabile ed in base al valore letto salta al case corrispondente.
Se il valore è 0 leggerà i comandi all’interno del case 0, nel nostro caso spegnerà il led e controllerà se si preme il pulsante, se questo viene premuto incrementa di 1 il valore della variabile stato.
Il comando break, dice solamente ad Arduino di non leggere i case successivi.
1 2 3 4 5 6 7 |
case 1: digitalWrite(5, HIGH); if(digitalRead(2)){ stato= stato+1; delay(300); } break; |
case 1, ossia cosa fare in caso il valore della variabile stato sia 1, in questo caso, Arduino accende il led e controlla sempre se viene premuto il pulsante, se questo viene premuto incrementa la variabile stato di 1
1 2 3 4 5 6 7 8 9 10 11 12 |
case 2: Dt = millis() -tempo; if( Dt >=500){ statoLed =! statoLed; digitalWrite( 5, statoLed); tempo= millis(); } if(digitalRead(2)){ stato= stato-2; delay(300); } break; |
Ultimo case della nostra macchina a stati, Arduino esegue un blink del led.
Quando la variabile stato ha valore 2, Arduino controlla che la differenza di tempo tra il valore di millis attuale e quello trascorso dall’ultimo cambio di stato del led, sia maggiore di 500ms, se questo è vero cambia lo stato del led, quindi se era acceso lo spegne e viceversa.
Intanto controlla se premiamo il pulsante, se questo avviene lo stato passera dal valore 2 al valore 0 e si spegnerà il led essendo tornati al case 0.
Come sempre vi lascio il link del simulatore:
simulazione switch case break
Nella pagina sono presenti link di affiliazione su cui si ottiene una piccola quota dei ricavi, senza variazioni dei prezzi.