Arduino – lezione 04: realizzare un programma che identifica le variazioni di stato

Prenderò spunto dal commento che mi è stato lasciato da un mio studente per introdurre l’uso delle istruzioni:

Lo scopo di questa lezione è quello di realizzare un programma che conta quante volte il pulsante viene premuto, per un ciclo di 4 pressioni, alla quinta pressione il led lampeggia una volta e poi si riavvia il ciclo.

Per questa lezione useremo:

  1. breadboard
  2. 4 diodi led
  3. 1 pulsante
  4. 1 resistenza da 10KOhm
  5. Arduino duemilanove

La prima versione del programma è quella che è stata realizzata dal mio studente, realizzazione di uno sketch per effettuare la seguente funzione:

Prima pressione: led lampeggia ogni mezzo secondo
Seconda pressione: led lampeggia ogni secondo
Terza pressione: led lampeggia ogni secondo e mezzo
Quarta pressione: led si spegne

Realizziamo un circuito come indicato nelle immagini che seguono:

La proposta interessante ed elegante dell’allievo, sfrutta l’istruzione “Switch Case” che permette di definire quale porzione di codice eseguire in funzione del valore di una variabile. Ciò consente di evitare lunghe catene di if-else.
Il “break” alla fine di ogni “case” viene usato per interrompere il controllo degli altri “case“.

Il programma come si intuisce dal filmato, presenta alcuni problemi.

Rimbalzo
Il problema dei segnali spuri dovuti al rimbalzo del pulsante non consente di controllare esattamente la selezione.

Attesa
Durante l’attesa, mentre si vede lampeggiare il led, premendo il pulsante non si ha cambiamento di stato fino a quando non termina il tempo in cui lampeggia il led.

Discriminare
Difficoltà di discriminare in quale situazione ci si trova, tempi troppo brevi per percepire la differenza delle 4 condizioni.

Per risolvere i problemi sopra elencati vi propongo 6 varianti all’esempio 1, ciò mi permetterà di introdurre nuove istruzioni del linguaggio di programmazione.

Prima di fornirvi le mie soluzioni ho necessità di introdurre l’uso dell’istruzioni Serial ed utilizzare il programma “StateChangeDetection” che potete trovare in File > Examples > 2.Digitale > StateChangeDetection o direttamente on-line sul sito Arduino che trovate di seguito

Il programma utilizza l’istruzione “Serial” usata per comunicare tra Arduino e il computer oppure altri dispositivi. La comunicazione tra Arduino e dispositivi esterni tramite la porta USB oppure tramite i pin 0 (RX) e 1 (TX). Ovviamente se si utilizzano i pin 1 e 0 per la comunicazione esterna, questi non potranno essere usati come input e output digitali.

All’interno dell’ambiente di sviluppo è implementata una shell per la comunicazione con la scheda, la trovate in Tools > Serial Monitor apparirà una finestra come quella rappresentata di seguito, in cui dovete specificare lo stesso baud rate che viene specificato nel begin().

Tornando al programma StateChangeDetection si noti

con cui apriamo la porta seriale USB e la inizializziamo a 9600 bps.

Nel programma troviamo l’istruzione:

println() stampa sulla console di uscita il testo specificato tra parentesi e tra virgolette: “on” seguito da un return (ASCII 13, o ‘\r’) e una nuova linea (ASCII 10, or ‘\n’).

print() nel nostro caso stampa sulla console di uscita il testo specificato tra parentesi e tra virgolette: “number of button pushes: “.

Dal reference on-line di Arduino
Con print() i numeri sono stampati utilizzando un carattere ASCII per ogni cifra, i float allo stesso modo ma con solo due numeri decimali, i byte vengono stampati come singoli caratteri, caratteri e stringhe vengono stampate senza nessuna conversione.

Esempio:

Serial.print(78) stampa “78”
Serial.print(1.23456) stampa “1.23”
Serial.print(byte(78)) stampa “N” (whose ASCII value is 78)
Serial.print(‘N’) stampa “N”
Serial.print(“Hello world.”) stampa “Hello world.”

print() può avere un secondo parametro che indica il formato usato nel primo parametro. Il formato può essere: BYTE, BIN (binario), OCT (ottale), DEC (decimale), HEX (esadecimale). Per i numeri in floating point il secondo parametro indica il numero di decimali presi in consideraione.

Per esempio:

Serial.print(78, BYTE) stampa “N”
Serial.print(78, BIN) stampa “1001110”
Serial.print(78, OCT) stampa “116”
Serial.print(78, DEC) stampa “78”
Serial.print(78, HEX) stampa “4E”
Serial.println(1.23456, 0) stampa “1”
Serial.println(1.23456, 2) stampa “1.23”
Serial.println(1.23456, 4) stampa “1.2346”

Torniamo all’analisi del programma CountStateDetection

buttonState = digitalRead(buttonPin);

immagazziniamo in buttonState lo stato del pulsante

controlliamo se il pulsante è stato premuto, cioè se lo stato attuale del pulsante è diverso da quello precedente, se la condizione è vera viene eseguita la porzione di codice che segue:


// if the state has changed, increment the counter
if (buttonState == HIGH) {
// if the current state is HIGH then the button
// wend from off to on:
buttonPushCounter++;
Serial.println(“on”);
Serial.print(“number of button pushes: “);
Serial.println(buttonPushCounter, DEC);
}
else {
// if the current state is LOW then the button
// wend from on to off:
Serial.println(“off”);
}

se buttonState è HIGH vuol dire che si è passati da pulsante non premuto a pulsante premuto,

incrementiamo di una unità la variabile che conta il numero di volte in cui il pulsante viene premuto

si noti che la notazione sopra è analoga alla seguente:

Successivamente con la porzione di codice:

stampiamo sul serial monitor il testo “on”, si va a capo, si stampa: “number of button pushes: ” seguito dalla stampa del numero di volte in cui il pulsante è stato premuto, dopo di che si va a capo.

Altrimenti se la condizione dell’if è falsa, cioè il pulsante non è premuto, viene eseguita la parte di codice dell’else e viene stampato “off”

Il passo successivo è quello di immagazzinare lo stato del pulsante in lastButtonState.

Nel caso in cui la condizione del primo if del loop() risulta falso, cioè il pulsante non è stato premuto, sarà eseguita la porzione di codice:

Si controlla se la divisione intera per 4 del contatore di pressione pulsante da resto zero, se vero ciò vuol dire che abbiamo premuto per quattro volte il pulsante, se falso, si esegue il codice nell’else, ciò vuol dire che non abbiamo premuto per 4 volte il pulsante ed il led viene mantenuto spento.
Ogni volta che si raggiungono 4 pressioni, si accende il led.

Ora incominciamo a dare soluzione al problema che ci siamo posti:
realizzare un programma che conta quante volte il pulsante viene premuto, per un ciclo di 4 pressioni, alla quinta pressione il led lampeggia una volta e poi si riavvia il ciclo.

La prima soluzione sfrutta una serie di if annidati:

come potete notare il programma è molto simile a CountStateDetection ma in questo caso verifico con una serie di if se il pulsante è stato premuto 1,2,3,4 volte,

alla quinta pressione, scriviamo a monitor: “fine ciclo”, facciamo lampeggiare il led per 50 millisecondi, stampiamo a monitor “mi riavvio” e si incomincia nuovamente il ciclo.

Poichè la visualizzazione dell’accensione del led alla quinta pressione del pulsante è troppo breve, facciamo in modo che alla quinta prssione il led lampeggi per 10 volte ad intervalli di 50 millisecondi, per far ciò utilizzerò un ciclo for (vai al reference on-line per la spiegazione).

La parte di codice che consente di far lampeggiare 10 volte il led è:

Si inizializza la viariabile intera x a 0 e ad ogni ciclo la si incrementa di 1 (x++)

Nel programma precedente, il controllo delle volte in cui il pulsante viene premuto è effettuato dalla serie di if:

dal punto di vista della programmazione ritengo più elegante e chiaro utilizzare l’istruzione case spiegato ad inizio lezione, questo è il codice:

L’esercizio che segue aggiunge un grado di difficoltà.
Negli esempi precedenti per controllare il numero di volte che il pulsante è stato premuto si è inviato un messaggio alla shell di output (Serial Monitor) se ricordate dai filmati l’output era questo:

Vogliamo ora, oltre che mandare messaggi alla shell di output, usare 4 led per identificare la pressione del pulsante.
Ad ogni pressione del pulsante si farà accende un led per volta e alla quinta pressione il primo led lampeggia per 10 volte.
Anche in questo caso il controllo del numero di volte in cui il pulsante viene premuto viene fatto con l’istruzione “case”.

Questo il circuito:

circuito02b-fz


Il programma:

Il programma differisce dalla versione precedente sostanzialmente nella parte iniziale in cui nominiamo i vari pin con nome del led corrispondente:

e nell’area dei “case” in cui come potete notare ad ogni pressione del pulsante viene spento il led precedente e acceso il successivo:

Lo scopo dell’ultimo esercizio è quello di creare un annidamento di “for“.
Anche in questo caso ad ogni pressione del pulsante si accende un led per volta però ora alla quinta pressione i led lampeggia per 5 volte in sequenza dal 4° al 1° led e poi si riavvia il ciclo.

I due cicli “for” sono nella parte terminale del programma:

Il ciclo “for” interno eseguirà 4 cicli (per n che va da 10 a 13). Come potete notare la variabile intera n viene inizializzata a 10 perché bisognerà accendere e poi spegnere prima il led connesso al pin 10, e così fino al diodo led connesso al pin 13 e questa sequenza sarà eseguita per 5 volte così come imposto dal ciclo “for” più esterno che eseguirà 5 (da 0 a 4) sequenze di accensione dei 4 led.

Bene!

Ora sapete usare le istruzioni: if, case e for e annidamento di for e sapete anche come inviare messaggi da Arduino al computer.


Vai alle altre lezioni:

Lezione01: Incominciamo con Arduino Arduino – lezione 02: facciamo lampeggiare un led Arduino – lezione 03: controlliamo un led con un pulsante
Lezione Arduino Lezione Arduino Lezione Arduino
Arduino – lezione 04: realizzare un programma che identifica le variazioni di stato Arduino – lezione 05: controllo presenza
Lezione Arduino Lezione Arduino

Articoli simili:

Questa voce è stata pubblicata in arduino e contrassegnata con , , , . Contrassegna il permalink.

19 risposte a Arduino – lezione 04: realizzare un programma che identifica le variazioni di stato

  1. Bertay scrive:

    volevo segnalarvi un concorso dove potete vincere la scheda arduino e non solo
    http://it.emcelettronica.com/marzuino-non-solo-arduino-ma-anche-oscilloscopio-digitale-multimetro-e

  2. admin scrive:

    Molto interessante la vostra iniziativa!
    Divulgherò sicuramente tra colleghi ed allievi.

    Cordiali saluti.

  3. massimo scrive:

    Molto bello l’articolo, vorrei solo aggiungere riguardo al sistema per gestire il fronte del pulsante che la soluzione classica è la seguente (e non occorre inizializzare le variabili):

    StatoPulsante = digitalRead(BUTTON);
    StatoChanged = (StatoPulsante) & (!StatoPulsanteOld); //non conosco bene la sintassi
    StatoPulsanteOld = digitalRead(BUTTON);
    if StatoChanged
    {
    }

  4. francesco scrive:

    Ottimo lavoro.

  5. Claudio scrive:

    Salve Prof.

    Tenendo in considerazione l’ esempio n°6. Perchè se tengo il pulsante premuto non fa il ciclo?? Qual è il comando che consente il “blocco”?

    Grazie
    Claudio

  6. maurizio scrive:

    Salve Professore
    sono da poco entrato nel mondo di arduino, i suoi tutorial sono molto interresanti e ben fatti.
    Io volevo chiedere un piccolo aiuto per un proggetto di domotica che vorrei realizzare.
    Per quanto riguarda lo sketch ho preso in considerazione e modificato quello creato da DOMOTICHOME.net, il mio problema e che vorrei comandare delle tende da sole che ad un primo impulso arduino attiva un’uscita per un tempo presatabilito dopo il quale viene disattivata, fino a qui tutto ok, quello che non riesco a realizzare e che durante la fase attiva se io voglio interrompere la stessa in un determinato momento prima del tempo prestabilito non me lo fa fare. Ho provato anche con alcuni esempi riportati nei suoi tutorial ma nulla da fare.
    Chiedo una mano
    grazie

  7. Pino scrive:

    Ciao,
    intanto volevo ringraziarla per il lavoro svolto, principalmente per noi alle prime armi!
    Ho una domanda, per gestire tutte le funzioni e i Pin della scheda, devo creare un solo File o posso fare diversi File (magari con nomi diversi)ognuno per ciascuna funzione che intendo realizzare ?
    Grazie, ciao.

  8. Mirko scrive:

    so che l’argomento è un po personale e forse non riguarda nemmemo raduino come programmazione !
    da poco tempo ho “arduino UNO” e ho letto i vostri articoli!
    ho provato a inserire un tasto come ingresso come spiegato nel vostro articolo!
    il risultato … un disastro ! l’ingresso mi manda una serie di segnali casuali apparentemente senza nessuna logica !
    tentato su altri ingressi ma il risultato sempre uguale !
    così pensando di aver bruciato arduino ho fatto un piccolo programma che mi indica una variazione sulle uscite per vedere se ci sono uscite ancora utilizzabili !
    tutto inutile le uscite ( anche quelle mai usate ) variano alimpazzata !
    avvicinando ( non toccando) una mano ad arduino il problema aumenta !
    alla fine mi sono accorto che sfiorando il terminale USB ( la parte metallica ) tutte le uscite si stabilizzano !
    cosa succede ?????
    grazie della vostra attenzione
    Mirko

  9. paolo scrive:

    salve a tutti, volevo chiedervi se era possibile modificare il programma di su, in modo che al posto di resettarsi per tornare indietro, si utilizzi un secondo pulsante per farlo, una specie di contatore up/down insomma, e quando si accende l’ultimo led, e continuo a premere up lui non faccia niente.. é possibile??
    cordiali saluti
    Paolo

  10. Gian Luca scrive:

    Buongiorno, da pochi giorni mi sto cimentando in questo bellissimo mondo… ho dei dubbi e dei problemi da principiante. Uno tra questi: effettuando la quarta lezione mi sono accorto che con una semplice pressione del bottone i segnali di input anzichè essere sempre uno a volte sono 2… posso chiedere il perchè e come posso risolvere questo problema? Grazie

  11. luigi basi scrive:

    Eccezzionale! per la chiarezza esauriente e perfetto.
    Bravi

  12. Luigi scrive:

    Nella seconda foto della Lezione 04, vedo che in LED è stato inserito direttamente tra GND e il terminale . Per la salute di ARDUINO, non è cosigliabile inserire una resistenza limitatrice da qualche centinaio di Hom ?
    Premetto che sono ai primi ma tengo a redermi conto delle cose.
    Complimenti vivissimi per i tutorial.

    • admin scrive:

      Ciao Luigi.

      Si hai ragione.
      In realtà è per la salute del LED. On-line troverai molti commenti a riguardo. Una reistenza di circa 220 Ohm va benissimo. Se non inserisci la resistenza, rischi di bruciare il LED, ma noterai che i LED comunemente usati per queste sperimentazioni (per capirci quelli di diametro 5mm) sono abbastanza resistenti e possono funzionare per brevi periodi anche in questa situazione anomale, in ogni caso non è da fare.

      Grazie per la precisazione.
      Ciao.

  13. Walter scrive:

    ATTENZIONE!!
    vorrei segnalare una imprecisione (abbastanza grave se si segue quello per realizzare il circuito in pratica!) sull’ultimo schema realizzato con fritzing:

    i diodi led sono collegati ai pin GND e +5V, inoltre sono pure collegati ai pin digitali di uscita 13,12,11,10. seguendo quello schema nel realizzare i collegamenti, al primo avvio penso che si rischia di mandare in corto circuito le uscite digitali di arduino, col rischio di rovinare l’intera schedina…

    invece dalle foto, su bread board è realizzato correttamente, con i catodi dei led collegati al pin GND, e gli anodi collegati ai soli pin digitali.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.