![03 Numerazione capitolo](03-num-capitolo.png) ## 03 - AMOROMETRO **TRASFORMA ARDUINO IN UNA MACCHINA DELL'AMORE. USANDO UN INGRESSO ANALOGICO, POTRAI MISURARE QUANTO SEI CALDO VERAMENTE!** > **Scopri:** ingresso analogico, monitor seriale > > **Tempo:** 45 MINUTI > **Livello:** ■ ■ □ □ □ > **Basato sui progetti:** 1, 2 **Pulsanti e interruttori sono una gran cosa, ma il mondo fisico è molto di più che non acceso e spento. Anche se Arduino è uno strumento digitale, può leggere informazioni da sensori analogici per misurare grandezze come la temperatura o la luce. Per farlo, utilizzerai il convertitore analogico-digitale (ADC) integrato nell'Arduino. I piedini di ingresso analogico A0-A5 restituiscono un valore compreso tra 0 e 1023 quando leggono delle tensioni comprese tra 0 e 5 volt.** ![Ingredienti](03-ingredienti.png) > **INGREDIENTI** > * 3 LED (Rossi) > * 3 Resistenze da 220 Ohm > * Sensore di temperatura (TMP36) ![Sensore temperatura](kit-sens-temperatura.png) > Userai un **sensore di temperatura** per misurare quanto è calda la tua pelle. Questo componente produce una tensione che varia in base alla temperatura percepita. Ha tre piedini: uno che si connette a massa, uno che si connette all'alimentazione e il terzo che produce una tensione variabile per Arduino. Nello sketch di questo progetto, leggerai il valore del sensore e lo userai per accendere e spegnere i LED, indicando quanto sei caldo. Esistono molti modelli di sensori di temperatura. Questo, il TMP36, è comodo perché produce una tensione in uscita che è direttamente proporzionale alla temperatura in gradi Celsius. L'ambiente di sviluppo integrato (IDE) di Arduino è dotato di uno strumento chiamato **monitor seriale** che ti consente di visualizzare dati provenienti dal microcontrollore. Usando il monitor seriale, è possibile ottenere informazioni sullo stato dei sensori e avere un'idea di ciò che sta accadendo nel circuito e nel codice. ![Monitor Seriale](03-immagine_monitor_seriale.png) *Fig.1: Monitor seriale.* ### COSTRUISCI IL CIRCUITO ![Schema del circuito e montaggio](03-immagine_circuito_amorometro.png) ![Schema elettrico](03-schema_elettrico.png) 1. Proprio come hai fatto nei progetti precedenti, collega la tua breadboard in modo da avere alimentazione e massa. 2. Collega a massa il catodo (il piedino corto) di ogni LED che stai usando attraverso una resistenza da 220 ohm. Collega gli anodi dei LED ai piedini dal 2 al 4. Questi saranno gli indicatori per il progetto. 3. Posiziona il TMP36 sulla breadboard con la parte piatta verso Arduino (l'ordine dei piedini è importante!) come mostrato in Fig. 2. Collega il piedino di sinistra della parte piatta all'alimentazione e il piedino destro a massa. Collega il piedino centrale al piedino A0 su Arduino. Questo è il piedino di ingresso analogico 0. ![Lente](lente.png) > In questo progetto, prima di procedere devi misurare la temperatura della stanza. Lo si può fare anche attraverso calibrazione. È possibile usare un pulsante per impostare la temperatura di riferimento o prendendo un campione con Arduino prima di iniziare il `loop()` e usarlo come punto di riferimento. Il progetto `06` scenderà nei dettagli di questo tema; puoi intanto guardare l'esempio di calibrazione che viene dato con il software di Arduino: arduino.org/calibration ![Forbici e colla](forbici-colla.png) > Crea un'interfaccia per il tuo sensore che permetta alle persone di interagrivi. Un ritaglio di carta a forma di mano è un buon indicatore. Se ti senti fortunato, crea un paio di labbra da baciare, guarda come si accendono le luci! Potresti etichettare i LED per dar loro un significato. Un LED potrebbe significare che sei un asociale, due LED che sei caldo e amichevole e tre che sei troppo caldo da gestire! ![Istruzioni per il ritaglio di carta](03-immagine_ritaglio_carta.png) *1. Ritaglia un pezzo di carta da posizionare sulla breadboard. Disegna delle labbra dove sarà messo il sensore e taglia alcuni cerchi per farci passare i LED.* *2. Posiziona il ritaglio sulla breadboard in modo che le labbra coprano il sensore e che i LED fuoriescano dai buchi. Premi le labbra per vedere quanto sei caldo!* ### IL CODICE #### Un paio di costanti utili Le costanti sono simili alle variabili: ti permettono di dare un nome univoco agli elementi presenti nel programma, ma, al contrario delle variabili, non possono cambiare. Dai un nome all'ingresso analogico per riconoscerlo facilmente e crea un'altra costante per la temperatura di base. Per ogni 2 gradi al di sopra di questo riferimento, si accende un LED. Hai già visto i tipi di dati `int`, usali qui per identificare su quale piedino è collegato il sensore. La temperatura è immagazzinata come un `float`, cioè un numero decimale. ```cpp const int sensorPin = A0; const float baselineTemp = 20.0; ``` #### Avvia la porta seriale alla velocità desiderata Nel `setup()` usa un nuovo comando, `Serial.begin()`, che apre una connessione tra l'Arduino e il computer, così puoi vedere il valore proveniente dall'ingresso analogico sullo schermo del computer. Il parametro `9600` è la velocità alla quale comunica l'Arduino: 9600 bit al secondo. Usa il monitor seriale dell'IDE di Arduino per visualizzare le informazioni che invii dal tuo microcontrollore. Quando apri il monitor seriale dell'IDE verifica che la velocità di trasmissione sia 9600. ```cpp void setup(){ Serial.begin(9600); // apri una porta seriale ``` #### Imposta le direzioni dei piedini digitali e spegnili Il prossimo è un ciclo `for()` per impostare alcuni piedini come uscite. Sono i piedini che in precedenza hai collegato ai LED. Invece di dare loro nomi unici e digitare la funzione `pinMode()` per ognuno di essi, puoi usare un ciclo `for()` per impostarli velocemente. Questo è un trucco comodo se hai un gran numero di cose simili che vuoi ripetere in un programma. Di' al ciclo `for()` di andare dal piedino 2 al 4 in modo sequenziale. ```cpp for(int pinNumber = 2; pinNumber<5; pinNumber++){ pinMode(pinNumber,OUTPUT); digitalWrite(pinNumber, LOW); } } ``` > **tutorial per il ciclo for()** > [arduino.cc/for](http://arduino.cc/for) #### Leggi il sensore di temperatura Nel `loop()`, usa una variabile locale chiamata `sensorVal` per immagazzinare le letture del sensore. Per ottenere il valore dal sensore, chiama `analogRead()` che richiede come parametro il numero del piedino dove leggere la tensione. Il valore, compreso tra 0 e 1023, rappresenta la tensione sul piedino. ```cpp void loop(){ int sensorVal = analogRead(sensorPin); ``` #### Invia i valori del sensore di temperatura al computer La funzione `Serial.print()` manda informazioni dall'Arduino al computer collegato. Puoi vedere questa informazione con il monitor seriale. Se dai al `Serial.print()` come parametro un testo tra virgolette, questo invia il testo che hai digitato. Se dai una variabile come parametro, invia il valore di quella variabile. ```cpp Serial.print("Sensor Value: "); Serial.print(sensorVal); ``` #### Converti la lettura del sensore in tensione Anche con poche conoscenze di matematica, è possibile determinare la reale tensione sul piedino. La tensione è tra 0 e 5 volt e potrebbe essere decimale (per esempio, potrebbe essere 2.5 volt), perciò hai bisogno di immagazzinarla in un `float`. Crea una variabile chiamata `voltage` per memorizzare questo numero. Dividi `sensorVal` per 1024.0 e moltiplicalo per 5.0. Il nuovo numero rappresenta la tensione sul piedino. Come con il valore del sensore, invialo al monitor seriale. ```cpp // converti la lettura ADC in tensione float voltage = (sensorVal/1024.0) * 5.0; Serial.print(", Volts: "); Serial.print(voltage); ``` #### Converti la tensione in temperatura e manda il valore al computer Se esamini la documentazione (*datasheet*) del sensore, trovi informazioni sui valori della tensione in uscita. I datasheet sono come manuali per i componenti elettronici. Sono stati scritti da ingegneri per altri ingegneri. Il datasheet di questo sensore spiega che una variazione di 10 millivolt del sensore è equivalente a un cambio di temperatura di 1 grado Celsius. Indica anche che il sensore può leggere temperature sotto gli 0 gradi. Per questo, devi creare una compensazione (offset) per i valori sotto gli 0 gradi. Se prendi la tensione, sottrai 0.5 e moltiplichi per 100, hai la temperatura accurata in gradi Celsius. Memorizza questo numero in una variabile `float` chiamata `temperature`. Ora che hai la temperatura vera, manda il valore al monitor seriale. Visto che la variabile `temperature` è l'ultima cosa che stampi in questo ciclo, puoi usare un comando leggermente differente: `Serial.println()`. Questo comando manda a capo il monitor seriale dopo l'invio del valore, aiutando a rendere più leggibili i dati visualizzati. ```cpp Serial.print(", degrees C: "); // converti la tensione in temperatura float temperature = (voltage - .5) * 100; Serial.println(temperature); ``` > **Starter Kit dei datasheet** > [arduino.cc/kitdatasheets](http://arduino.cc/kitdatasheets) #### Spegni i LED con una temperatura bassa Con la temperatura vera puoi usare un'istruzione `if()...else` per accendere i LED. Usando la temperatura di riferimento come punto di partenza, accendi un LED per ogni aumento di temperatura di 2 gradi. Cerca diversi intervalli di valori mentre ti muovi sulla scala delle temperature. ```cpp if(temperature < baselineTemp){ digitalWrite(2, LOW); digitalWrite(3, LOW); digitalWrite(4, LOW); } ``` #### Accendi un LED a una bassa temperatura L'operatore `&&` significa "e" (and), in senso logico. Puoi verificare più condizioni come se la temperatura è di 2 gradi più alta del riferimento e meno di 4 gradi sopra di essa. ```cpp else if(temperature >= baselineTemp+2 && temperature < baselineTemp+4){ digitalWrite(2, HIGH); digitalWrite(3, LOW); digitalWrite(4, LOW); } ``` #### Accendi due LED a una temperatura media Se la temperatura è tra 2 e 4 gradi sopra il riferimento, questo blocco di codice accende anche il LED sul piedino 3. ```cpp else if(temperature >= baselineTemp+4 && temperature < baselineTemp+6){ digitalWrite(2, HIGH); digitalWrite(3, HIGH); digitalWrite(4, LOW); } ``` #### Accendi tre LED a un'alta temperatura ```cpp else if(temperature >= baselineTemp+6){ digitalWrite(2, HIGH); digitalWrite(3, HIGH); digitalWrite(4, HIGH); } ``` Il convertitore digitale-analogico non può leggere velocissimamente così dovresti inserire un leggero ritardo alla fine del tuo `loop()`. Se lo leggi troppo di frequente, i tuoi valori appaiono irregolari. ```cpp delay(1); } ``` ### USALO ![Pulsante monitor seriale](03-usa-monito-seriale.png) Con il codice caricato su Arduino, clicca l'icona del monitor seriale. Dovresti vedere un flusso di valori così formattati: **Sensor: 200, Volts: .70, degrees C: 17** Metti le dita intorno al sensore quando è collegato alla breadboard e guarda cosa accade ai valori nel monitor seriale. Prendi nota della temperatura quando il sensore è lasciato all'aria aperta. Chiudi il monitor seriale e imposta la costante del riferimento di temperatura al valore della temperatura ambiente. Carica ancora il codice e prova a tenere il sensore tra le dita. Mentre la temperatura aumenta, dovresti vedere accendersi i LED uno a uno. Congratulazioni! ![Cervello](cervello.png) > Crea un'interfaccia per due persone per testare la loro compatibilità reciproca. Decidi cosa significa compatibilità e come la leggerai: Forse si sono tenuti la mano e hanno generato calore? Forse si sono abbracciati? Cosa ne pensi? **Espandendo i tipi di ingressi che puoi leggere, hai usato `analogRead()` e il monitor seriale per tenere traccia dei cambiamenti dentro Arduino. Ora è possibile leggere un gran numero di sensori analogici.** ### CODICE COMPLETO ```cpp /* Arduino Starter Kit example Project 3 - Love-O-Meter This sketch is written to accompany Project 3 in the Arduino Starter Kit Parts required: - one TMP36 temperature sensor - three red LEDs - 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. */ // named constant for the pin the sensor is connected to const int sensorPin = A0; // room temperature in Celsius const float baselineTemp = 20.0; void setup() { // open a serial connection to display values Serial.begin(9600); // set the LED pins as outputs // the for() loop saves some extra coding for (int pinNumber = 2; pinNumber < 5; pinNumber++) { pinMode(pinNumber, OUTPUT); digitalWrite(pinNumber, LOW); } } void loop() { // read the value on AnalogIn pin 0 and store it in a variable int sensorVal = analogRead(sensorPin); // send the 10-bit sensor value out the serial port Serial.print("sensor Value: "); Serial.print(sensorVal); // convert the ADC reading to voltage float voltage = (sensorVal / 1024.0) * 5.0; // Send the voltage level out the Serial port Serial.print(", Volts: "); Serial.print(voltage); // convert the voltage to temperature in degrees C // the sensor changes 10 mV per degree // the datasheet says there's a 500 mV offset // ((voltage - 500 mV) times 100) Serial.print(", degrees C: "); float temperature = (voltage - .5) * 100; Serial.println(temperature); // if the current temperature is lower than the baseline turn off all LEDs if (temperature < baselineTemp + 2) { digitalWrite(2, LOW); digitalWrite(3, LOW); digitalWrite(4, LOW); } // if the temperature rises 2-4 degrees, turn an LED on else if (temperature >= baselineTemp + 2 && temperature < baselineTemp + 4) { digitalWrite(2, HIGH); digitalWrite(3, LOW); digitalWrite(4, LOW); } // if the temperature rises 4-6 degrees, turn a second LED on else if (temperature >= baselineTemp + 4 && temperature < baselineTemp + 6) { digitalWrite(2, HIGH); digitalWrite(3, HIGH); digitalWrite(4, LOW); } // if the temperature rises more than 6 degrees, turn all LEDs on else if (temperature >= baselineTemp + 6) { digitalWrite(2, HIGH); digitalWrite(3, HIGH); digitalWrite(4, HIGH); } delay(1); } ``` Variante per utilizzo con [LM](https://octopart.com/it/part/texas-instruments/LM35DH)35 ```cpp /* Arduino Starter Kit example Project 3 - Love-O-Meter This sketch is written to accompany Project 3 in the Arduino Starter Kit Parts required: - one LM35 temperature sensor - three red LEDs - 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. */ // named constant for the pin the sensor is connected to const int sensorPin = A0; // room temperature in Celsius const float baselineTemp = 20.0; void setup() { // open a serial connection to display values Serial.begin(9600); //Switch to Internal 1.1V Reference analogReference(INTERNAL); // set the LED pins as outputs // the for() loop saves some extra coding for (int pinNumber = 2; pinNumber < 5; pinNumber++) { pinMode(pinNumber, OUTPUT); digitalWrite(pinNumber, LOW); } } void loop() { // read the value on AnalogIn pin 0 and store it in a variable double sensorVal = analogRead(sensorPin); // send the 10-bit sensor value out the serial port Serial.print("sensor Value: "); Serial.print(sensorVal); // convert the ADC reading to voltage double voltage = (sensorVal * 1100) / 1024; // Send the voltage level out the Serial port Serial.print(", Volts: "); Serial.print(voltage); // convert the voltage to temperature in degrees C // the sensor changes 10 mV per degree // the datasheet says there's a 500 mV offset // ((voltage - 500 mV) times 100) Serial.print(", degrees C: "); double temperature = voltage / 10; Serial.println(temperature); // if the current temperature is lower than the baseline turn off all LEDs if (temperature < baselineTemp + 2) { digitalWrite(2, LOW); digitalWrite(3, LOW); digitalWrite(4, LOW); } // if the temperature rises 2-4 degrees, turn an LED on else if (temperature >= baselineTemp + 2 && temperature < baselineTemp + 4) { digitalWrite(2, HIGH); digitalWrite(3, LOW); digitalWrite(4, LOW); } // if the temperature rises 4-6 degrees, turn a second LED on else if (temperature >= baselineTemp + 4 && temperature < baselineTemp + 6) { digitalWrite(2, HIGH); digitalWrite(3, HIGH); digitalWrite(4, LOW); } // if the temperature rises more than 6 degrees, turn all LEDs on else if (temperature >= baselineTemp + 6) { digitalWrite(2, HIGH); digitalWrite(3, HIGH); digitalWrite(4, HIGH); } delay(1); } ```