![02 Numerazione capitolo](02-num-capitolo.png) ## 02 - INTERFACCIA PER ASTRONAVE **ARDUINO STA PER DIVENTARE IL PROTAGONISTA DI UN FILM DI FANTASCIENZA** > **Scopri:** input e output digitali, il tuo primo programma, le variabili > > **Tempo:** 45 MINUTI > **Livello:** ■ □ □ □ □ > **Basato sul progetto:** 1 **Ora che hai acquisito le basi dell'elettronica, è tempo di passare a controllare cose e oggetti con Arduino. In questo progetto, costruirai qualcosa che potrebbe essere un'interfaccia di una astronave di un film di fantascienza degli anni Settanta. Realizzerai un pannello di controllo con un pulsante e delle luci che si accenderanno quando schiaccerai il pulsante. Puoi decidere se le luci significano "Inserire l'hyperdrive" o "Spara il laser!". Un LED verde sarà acceso finché non premerai un pulsante. Quando Arduino riceverà un segnale da un pulsante, la luce verde si spegnerà e le altre due luci inizieranno a lampeggiare.** ![Ingredienti: pulsante LED resistenza 220 Ohm Resistenza 10 kOhm](02-ingredienti.png) > **INGREDIENTI** > * Pulsante > * LED > * Resistenza da 220 Ohm > * Resistenza da 10 kilo Ohm I piedini digitali di Arduino possono leggere solo due stati: quando c'è o non c'è la tensione su un piedino di ingresso. Questo tipo di ingresso è chiamato digitale (o qualche volta binario, per via dei due stati). Questi stati vengono definiti come ALTO (**HIGH**) e BASSO (**LOW**). **HIGH** è come dire "c'è tensione qui!" e **LOW** significa "non c'è tensione su questo piedino!". Quando metti un piedino di **OUTPUT** a **HIGH**, usando un comando chiamato `digitalWrite()`, lo stai accendendo. Se misuri la tensione tra il piedino e la massa, ottieni 5 volt. Quando metti un piedino di **OUTPUT** a **LOW**, lo stai spegnendo. Il piedino digitale di Arduino funziona sia come ingresso sia come uscita. Nel tuo codice, dovrai configurarli a seconda della funzione che vorrai dare loro. Quando i piedini sono output (uscita), puoi accendere componenti come i LED. Se configuri i piedini come input (ingresso), puoi verificare se è stato premuto o no un pulsante. Dato che i piedini 0 e 1 sono usati per comunicare con il computer, è meglio iniziare con il piedino 2. ### COSTRUISCI IL CIRCUITO ![Diagramma del circuito](02-immagine_circuito_astronave.png) ![Schema elettrico circuito](02-schema_elettrico_circuito_astronave.png) 1. Collega la breadboard alle connessioni 5V e GND (massa) di Arduino, come nel progetto precedente. Posiziona due LED rossi e uno verde sulla breadboard. Connetti il catodo (piedino corto) di ciascun LED a massa attraverso una resistenza da 220 ohm. Connetti l'anodo (piedino lungo) del LED verde al piedino 3. Connetti gli anodi dei LED rossi rispettivamente ai piedini 4 e 5. 2. Posiziona l'interruttore sulla breadboard come nel progetto precedente. Connetti un lato all'alimentazione e l'altro lato al piedino digitale 2 di Arduino. Hai anche bisogno di aggiungere una resistenza da 10 kilo ohm da massa al piedino dell'interruttore che è collegato ad Arduino. Questa resistenza di 'pull-down' connette il piedino a massa quando il pulsante è aperto, così si legge **LOW** quando nessuna tensione proviene dal pulsante. ![Forbici e colla](forbici-colla.png) > Puoi coprire la breadboard con il cartoncino del kit. O puoi decorarlo per realizzare il tuo personale sistema di lancio. Se le luci si accendono e si spengono non significa nulla di per sé, ma, quando le metti in un pannello di controllo e dai loro un senso, acquistano un significato maggiore. Cosa vuoi che significhi il LED verde? E il lampeggio del LED rosso? Sei libero di deciderlo! > Trovi il modello da ritagliare nel capitolo PAPERCRAFT, in fondo al testo. ![Istruzioni per il cartoncino pieghevole](02-immagine_cartoncino_astronave.png) *1. Piega il cartoncino pre-tagliato come mostrato qui.* *2. Metti il cartoncino piegato sulla breadboard. I tre LED e il pulsante aiutano a trovare la posizione.* ### IL CODICE #### Alcune note prima di iniziare Ogni programma Arduino ha due funzioni principali. Le funzioni sono parti di un programma del computer che eseguono comandi specifici. Le funzioni hanno nomi univoci e sono 'chiamate' quando servono. Le funzioni necessarie in un programma Arduino sono chiamate `setup()` e `loop()`. Queste funzioni devono essere dichiarate: significa che si deve dire ad Arduino cosa faranno. `setup()` e `loop()` sono indicate come vedi sulla destra. In questo programma, stai per creare una variabile prima di entrare nella parte principale del programma. Le variabili sono nomi che dai a delle aree di memoria di Arduino così puoi tenere traccia di ciò che sta accadendo. Questi valori possono cambiare a seconda delle istruzioni del tuo programma. I nomi delle variabili dovrebbero essere descrittivi dei valori che stanno immagazzinando. Per esempio, una variabile chiamata `switchState` spiega cosa sta immagazzinando: lo stato di un pulsante. Invece, una variabile chiamata `x` non spiega nulla su ciò che contiene. ```cpp void setup() { } void loop() { } ``` > **Parentesi graffe { }** > Il codice scritto all'interno di parentesi graffe è eseguito quando viene chiamata la funzione. #### Iniziamo a programmare Per creare una variabile, hai bisogno di dichiararne il tipo. Il tipo di dato `int` contiene un numero intero (chiamato anche un intero); che è un numero qualsiasi senza punti decimali. Quando dichiari una variabile, normalmente gli dai anche un valore iniziale. La dichiarazione della variabile deve finire con un punto e virgola (;). ```cpp int switchState = 0; ``` #### Configura la funzionalità dei piedini Il `setup()` viene eseguito una volta soltanto all'accensione dell'Arduino. Qui è dove configuri i piedini digitali per renderli ingressi o uscite usando la funzione `pinMode()`. I piedini connessi ai LED sono uscite (OUTPUT) e il pulsante un ingresso (INPUT). ```cpp void setup() { pinMode(3, OUTPUT); pinMode(4, OUTPUT); pinMode(5, OUTPUT); pinMode(2, INPUT); } ``` > **Maiuscole, minuscole** > Nel codice stai attento a distinguere le maiuscole e le minuscole. Per esempio, `pinMode` è il nome di un comando, ma `pinmode` produce un errore. #### Crea la funzione loop Il `loop()` viene eseguito continuamente dopo che è stato completato il `setup()`. Il `loop()` è il posto dove verifichi la tensione sugli ingressi e controlli le uscite. Per controllare la tensione su un input digitale, usa la funzione `digitalRead()` che rileva se c'è tensione sul piedino scelto. Per sapere quale piedino leggere, `digitalRead()` si aspetta un parametro. I parametri sono informazioni che dai alle funzioni dicendo loro come dovrebbero svolgere il loro lavoro. Per esempio, `digitalRead()` ha bisogno di un parametro: quale piedino leggere. Nel tuo programma, `digitalRead()` sta verificando lo stato del piedino 2 e immagazzinando il valore nella variabile `switchState`. Se c'è tensione sul piedino quando viene chiamata `digitalRead()`, la variabile `switchState` ha il valore **HIGH** (o 1). Se non c'è tensione, `switchState` prende il valore **LOW** (o 0). ```cpp void loop() { switchState = digitalRead(2); // questo è un commento ``` > **Commenti** > I commenti sono note che scrivi per te stesso, che il computer ignora. Per scrivere un commento, aggiungi due barre `//`. Il computer ignora tutto il contenuto presente dopo le due barre. #### L'istruzione if Un comando `if()` nella programmazione confronta due cose e determina se il confronto è vero o falso ed esegue le azioni che gli indichi. Quando confronti due cose nella programmazione, devi usare due simboli dell'uguale `==`. Se usi un segno solo, imposti il valore della variabile invece di confrontarlo. ```cpp if (switchState == LOW) { // il pulsante non è premuto ``` #### Costruisci la tua astronave `digitalWrite()` è il comando che ti permette di impostare un'uscita a 5V o 0V. `digitalWrite()` richiede due parametri: quale piedino controllare e a quale valore impostare il piedino, **HIGH** o **LOW**. Se vuoi accendere i LED rossi e spegnere il LED verde nella tua istruzione `if()`, il tuo codice sarà così. ```cpp digitalWrite(3, HIGH); // LED verde digitalWrite(4, LOW); // LED rosso digitalWrite(5, LOW); // LED rosso } ``` > Può essere utile trascrivere il flusso del programma in pseudocodice: un modo per descrivere cosa vuoi che il programma faccia in un linguaggio semplice, ma strutturato in modo che renda facile scrivere un vero programma. In questo caso stai determinando se `switchState` è HIGH (significa che il pulsante è premuto) o no. Se il pulsante è premuto, spegnerai il LED verde e accenderai quello rosso. Nel pseudocodice, il comando potrebbe essere così: > > `se switchState è LOW:` > `____accendi il LED verde` > `____spegni il LED rosso` > ` se switchState è HIGH:` > `____spegni il LED verde` > `____accendi il LED rosso` **Se ora esegui il tuo programma, le luci cambiano quando premi il pulsante. Questo è piuttosto chiaro, ma puoi aggiungere un tocco di complessità al programma per una reazione più interessante.** Hai detto ad Arduino cosa fare quando l'interruttore è aperto. Ora definisci cosa accade quando è chiuso. L'istruzione `if()` ha un componente opzionale `else` (in italiano oppure) che fa succedere qualcosa se la condizione originale non si è verificata. In questo caso, dato che hai verificato che il pulsante è **LOW**, scrivi il codice per la condizione **HIGH** dopo l'istruzione `else`. Per far lampeggiare i LED rossi quando è premuto il pulsante, devi accendere e spegnere le luci nell'istruzione `else` che hai appena scritto. ```cpp else { // il pulsante è premuto digitalWrite(3, LOW); digitalWrite(4, LOW); digitalWrite(5, HIGH); ``` **Ora il tuo programma fa lampeggiare il LED rosso quando il pulsante è premuto.** Dopo aver impostato i LED in un determinato stato, devi mettere in pausa l'Arduino prima di riportarli allo stato precedente. Se non aspetti, le luci vanno avanti e indietro così velocemente che appaiono leggermente meno luminose ma non accese o spente. Questo perché l'Arduino esegue il suo `loop()` migliaia di volte ogni secondo e il LED si accende e spegne più velocemente di quanto riusciamo a percepirlo. La funzione `delay()` impedisce ad Arduino di eseguire istruzioni per un certo periodo di tempo. `delay()` richiede un parametro che determina il numero di millisecondi prima di eseguire le istruzioni successive. Ci sono 1000 millisecondi in un secondo. `delay(250)` fa pausa per un quarto di secondo. ```cpp delay(250); // aspetta un quarto di secondo // cambia gli stati dei LED digitalWrite(4, HIGH); digitalWrite(5, LOW); delay(250); // aspetta un quarto di secondo } } // torna indietro all'inizio del loop ``` ### USALA Una volta che la tua Arduino è programmata, dovresti vedere accendersi la luce verde. Quando premi il pulsante, le luci rosse iniziano a lampeggiare e la luce verde si spegne. Prova a cambiare il tempo delle due funzioni `delay()`: nota cosa accade alle luci e come la risposta del sistema cambia in base alla velocità del lampeggio. Quando esegui un `delay()` nel programma, questo ferma tutte le altre funzionalità. Non avviene nessuna lettura di sensori fino a che questo periodo non è passato. Sebbene i ritardi siano spesso utili, quando realizzi il tuo progetto assicurati che non interferiscano inutilmente con l'interfaccia. ![Cervello](cervello.png) > Come potresti far lampeggiare i LED rossi quando si avvia il programma? Come potresti creare un'interfaccia più grande o più complessa con LED e pulsanti per le tue avventure interstellari? ![Lente](lente.png) > Quando inizi a creare un'interfaccia per il tuo progetto, pensa alle aspettative delle persone che lo useranno. Quando premono un pulsante, vorranno un feedback immediato? Dovrebbe esserci un ritardo tra le loro azioni e ciò che fa Arduino? Prova a metterti nei panni di un altro quando stai progettando e verifica che le tue aspettative siano adeguate alla realtà del progetto.* **In questo progetto, hai creato il tuo primo programma con Arduino per controllare con un pulsante il comportamento di alcuni LED. Hai usato delle variabili, un'istruzione if()... e funzioni per leggere lo stato di un ingresso e controllare delle uscite.** ### COME LEGGERE IL CODICE COLORI DELLE RESISTENZE ![Grafico codici colori resistenze](02-immagine_codici_resistenze.png) I valori delle resistenze sono espressi da anelli colorati secondo una norma sviluppata negli anni Venti quando era troppo complesso scrivere numeri su oggetti tanto piccoli. Ogni colore corrisponde a un numero, come vedi nella tabella sotto. Ogni resistenza ha 4 o 5 anelli. Nel tipo con 4 anelli, i primi due anelli indicano le prime due cifre del valore mentre il terzo indica il numero degli zero seguenti (tecnicamente rappresenta la potenza di dieci). L'ultimo anello specifica la tolleranza: nell'esempio qui sotto, l'oro indica che il valore della resistenza può essere 10 kilo ohm più o meno 5%. **RESISTENZE CONTENUTE NELLO STARTER KIT** (Troverai versioni con 4 e 5 fasce) * **220 Ω** (Rosso, Rosso, Marrone, Oro / Rosso, Rosso, Nero, Nero, Marrone) * **560 Ω** (Verde, Blu, Marrone, Oro / Verde, Blu, Nero, Nero, Marrone) * **4.7 kΩ** (Giallo, Viola, Rosso, Oro / Giallo, Viola, Nero, Marrone, Marrone) * **1 kΩ** (Marrone, Nero, Rosso, Oro / Marrone, Nero, Nero, Marrone, Marrone) * **10 kΩ** (Marrone, Nero, Arancione, Oro / Marrone, Nero, Nero, Rosso, Marrone) * **1 MΩ** (Marrone, Nero, Verde, Oro / Marrone, Nero, Nero, Giallo, Marrone) * **10 MΩ** (Marrone, Nero, Blu, Oro / Marrone, Nero, Nero, Verde, Marrone) ### CODICE COMPLETO ```cpp /* Arduino Starter Kit example Project 2 - Spaceship Interface This sketch is written to accompany Project 2 in the Arduino Starter Kit Parts required: - one green LED - two red LEDs - pushbutton - 10 kilohm resistor - three 220 ohm resistors created 13 Sep 2012 by Scott Fitzgerald https://store.arduino.cc/genuino-starter-kit This example code is part of the public domain. */ // Create a global variable to hold the state of the switch. This variable is // persistent throughout the program. Whenever you refer to switchState, you’re // talking about the number it holds int switchstate = 0; void setup() { // declare the LED pins as outputs pinMode(3, OUTPUT); pinMode(4, OUTPUT); pinMode(5, OUTPUT); // declare the switch pin as an input pinMode(2, INPUT); } void loop() { // read the value of the switch // digitalRead() checks to see if there is voltage on the pin or not switchstate = digitalRead(2); // if the button is not pressed turn on the green LED and off the red LEDs if (switchstate == LOW) { digitalWrite(3, HIGH); // turn the green LED on pin 3 on digitalWrite(4, LOW); // turn the red LED on pin 4 off digitalWrite(5, LOW); // turn the red LED on pin 5 off } // this else is part of the above if() statement. // if the switch is not LOW (the button is pressed) turn off the green LED and // blink alternatively the red LEDs else { digitalWrite(3, LOW); // turn the green LED on pin 3 off digitalWrite(4, LOW); // turn the red LED on pin 4 off digitalWrite(5, HIGH); // turn the red LED on pin 5 on // wait for a quarter second before changing the light delay(250); digitalWrite(4, HIGH); // turn the red LED on pin 4 on digitalWrite(5, LOW); // turn the red LED on pin 5 off // wait for a quarter second before changing the light delay(250); } } ```