![04 Numerazione capitolo](04-num-capitolo.png) ## 04 - LAMPADA MISCELA COLORI **USANDO UN LED A TRE COLORI E TRE FOTORESISTENZE, POTRAI CREARE UNA LAMPADA CHE CAMBIA COLORE IN BASE ALLE CONDIZIONI ESTERNE DI LUCE** > **Scopri:** uscite analogiche, mappare valori > > **Tempo:** 45 MINUTI > **Livello:** ■ ■ ■ □ □ > **Basato sui progetti:** 1, 2, 3 **Far lampeggiare i LED può essere divertente, ma che ne pensi di farli sfumare o miscelarne i colori? Ti potresti aspettare che si tratti solo di fornire meno tensione a un LED per fargli cambiare luminosità.** ![Ingredienti](04-ingredienti.png) >**INGREDIENTI** >* LED RGB (Catodo comune) >* 3 Fotoresistenze >* 3 Resistenze da 10 kΩ >* 3 Resistenze da 220 Ω >* Filtri colorati (Gelatine: Rosso, Verde, Blu) Arduino non può variare la tensione d'uscita dei suoi piedini che può essere solo di 5V. Quindi avrai bisogno di una tecnica chiamata modulazione di larghezza di impulso – in inglese **Pulse Width Modulation (PWM)** – per attenuare i LED. La modulazione di larghezza di impulso accende e spegne rapidamente i piedini di uscita in un determinato intervallo di tempo. Il cambiamento avviene più velocemente di quanto l'occhio umano possa percepire. È simile al modo in cui funziona il cinema: mostrare velocemente una serie di immagini fisse per creare l'illusione del movimento. Quando fai passare velocemente il piedino da **HIGH** a **LOW**, è come se stessi cambiando la tensione. La percentuale di tempo in cui un piedino è **HIGH** in un periodo è chiamata *duty cycle* o ciclo di lavoro utile. Quando il piedino è **HIGH** per metà di un periodo e **LOW** per l'altra metà, il ciclo di lavoro è 50%. Un ciclo di lavoro più basso produce un LED più attenuato che un ciclo di lavoro più alto. ![Diagramma PWM](04-immagine_diagramma_pwm.png) Arduino Uno ha sei piedini riservati al PWM (**piedini digitali 3, 5, 6, 9, 10 e 11**): sono identificati da **~** accanto al loro numero sulla scheda. ![Fotoresistenza](kit-fotoresistenza.png) In questo progetto come ingressi userai delle **fotoresistenze** (sensori che cambiano la loro resistenza secondo la quantità di luce che li colpisce; sono conosciuti anche come fotocellule o fotorivelatori). Se ne colleghi una estremità ad Arduino, puoi misurare il cambiamento di resistenza controllando la tensione sul piedino. ### COSTRUISCI IL CIRCUITO ![Schema del circuito e montaggio](04-immagine_circuito_lampada.png) ![Schema montaggio](04-montaggio.png) 1. Collega la breadboard così hai alimentazione e massa su entrambi i lati, come nei progetti precedenti. 2. Metti tre fotoresistenze sulla breadboard a cavallo del separatore centrale come in Fig. 1. Collega una estremità di ogni fotoresistenza all'alimentazione. Sull'altro lato, collega a massa una resistenza da 10 kilo ohm. Questa resistenza è in serie con la fotoresistenza, e insieme formano un partitore di tensione. La tensione nel punto in cui si incontrano è proporzionale al rapporto delle loro resistenze, secondo la legge di Ohm (vedi il Progetto 01 per maggiori dettagli sulla legge di Ohm). Al variare della luce che colpisce la fotoresistenza cambia la tensione nel punto di contatto. Sullo stesso lato della resistenza, collega le fotoresistenze agli ingressi analogici 0, 1 e 2 con un ponticello. 3. Prendi tre filtri colorati e posizionali ciascuno su una fotoresistenza. Metti il filtro rosso sulla fotoresistenza collegata all'A0, il verde su quella collegata all'A1 e il blu su quella collegata all'A2. Ognuno di questi filtri consente solo alla luce di una specifica lunghezza d'onda di arrivare al sensore. Il filtro rosso fa passare solo luce rossa, il filtro verde solo luce verde e il filtro blu solo luce blu. Questo permette di rilevare i livelli di colore nella luce che colpisce i sensori. 4. Il LED con 4 gambe è un LED RGB a catodo comune. Il LED contiene tre elementi separati – rosso, verde e blu – e una massa comune (il catodo). Creando una differenza di tensione tra il catodo e la tensione d'uscita dei piedini PWM dell'Arduino (che sono connessi agli anodi attraverso resistenze da 220 ohm), il LED sfuma nei tre colori. Prendi nota di quale sia il piedino più lungo sul LED, posizionalo sulla breadboard e collegalo a massa. Collega gli altri tre piedini alle uscite digitali 9, 10 e 11, tramite le resistenze da 220 ohm. Assicurati di collegare ogni LED al piedino PWM corretto, seguendo l'immagine a sinistra. ![Led RGB](04-led_RGB.png) *LED rgb* ![Schema elettrico](04-schema_elettrico.png) *Fig.3: Schema elettrico.* ### IL CODICE #### Costanti utili Imposta le costanti per i piedini che stai usando come ingressi e uscite, così puoi tenere traccia di quale sensore si accoppia con quale colore del LED. Usa `const int` come tipo di dato. ```cpp const int greenLEDPin = 9; const int redLEDPin = 11; const int blueLEDPin = 10; const int redSensorPin = A0; const int greenSensorPin = A1; const int blueSensorPin = A2; ``` #### Variabili per immagazzinare le letture dei sensori e il livello di luce di ogni LED Aggiungi variabili per i valori dei sensori in ingresso e per i valori di luminosità dei LED. Si può usare il tipo di dati `int` per tutte le variabili. ```cpp int redValue = 0; int greenValue = 0; int blueValue = 0; int redSensorValue = 0; int greenSensorValue = 0; int blueSensorValue = 0; ``` #### Imposta la direzione dei piedini digitali e configura la porta seriale Nel `setup()`, avvia la comunicazione seriale a 9600 bps. Come nell'esempio precedente, la usi per visualizzare i valori dei sensori tramite il monitor seriale. Inoltre, puoi vedere i valori mappati che utilizzi per sfumare il LED. Inoltre, definisci i piedini del LED come uscite con `pinMode()`. ```cpp void setup() { Serial.begin(9600); pinMode(greenLEDPin, OUTPUT); pinMode(redLEDPin, OUTPUT); pinMode(blueLEDPin, OUTPUT); } ``` #### Leggi il valore di ogni sensore di luce Nel `loop()` leggi i valori del sensore sui piedini A0, A1 e A2 con `analogRead()` e memorizza il valore delle variabili. Metti un breve `delay()` tra ogni `analogRead()` per dar tempo all'ADC (convertitore analogico-digitale) di fare il suo lavoro. ```cpp void loop() { redSensorValue = analogRead(redSensorPin); delay(5); greenSensorValue = analogRead(greenSensorPin); delay(5); blueSensorValue = analogRead(blueSensorPin); ``` #### Riporta le letture del sensore al computer Riporta su una riga i valori del sensore. `"\t"` è equivalente a premere il tasto **"tab"** sulla tastiera. ```cpp Serial.print("Raw Sensor Values \t Red: "); Serial.print(redSensorValue); Serial.print("\t Green: "); Serial.print(greenSensorValue); Serial.print("\t Blue: "); Serial.println(blueSensorValue); ``` #### Converti le letture dei sensori La funzione per modificare la luminosità dei LED tramite PWM è `analogWrite()`. Ha bisogno di due parametri: il piedino da modificare e un valore tra 0 e 255. Il secondo rappresenta il ciclo di lavoro che Arduino produce sul piedino specificato. Un valore di 255 imposta il piedino **HIGH** per tutto il tempo, portando alla massima luminosità il LED collegato. Un valore di 127 imposta il piedino **HIGH** per metà del periodo, rendendo il LED più sfumato. Il valore 0 imposta il piedino **LOW** per tutto il tempo, spegnendo il LED. Per convertire la lettura di un sensore da un valore tra 0 e 1023 a uno tra 0 e 255 per `analogWrite()`, dividi per 4 la lettura del sensore. ```cpp redValue = redSensorValue/4; greenValue = greenSensorValue/4; blueValue = blueSensorValue/4; ``` #### Riporta i livelli di luce del LED che sono stati calcolati Invia i nuovi valori mappati su una riga separata. ```cpp Serial.print("Mapped Sensor Values \t Red: "); Serial.print(redValue); Serial.print("\t Green: "); Serial.print(greenValue); Serial.print("\t Blue: "); Serial.println(blueValue); ``` #### Imposta i livelli di luce del LED ```cpp analogWrite(redLEDPin, redValue); analogWrite(greenLEDPin, greenValue); analogWrite(blueLEDPin, blueValue); } ``` ### USALA Quando hai programmato e collegato Arduino, apri il monitor seriale. Il LED è probabilmente di un colore biancastro, a seconda del colore predominante della luce nella tua stanza. Guarda i valori provenienti dai sensori nel monitor seriale: se sei in un ambiente con illuminazione stabile, il numero sarà probabilmente abbastanza consistente. Spegni la luce nella stanza in cui stai lavorando e guarda cosa succede ai valori dei sensori. Con una torcia elettrica, illumina ogni sensore e nota come i valori cambiano nel monitor seriale e come il LED cambia colore. Quando le fotoresistenze sono coperte con un filtro, reagiscono solo alla luce di una certa lunghezza d'onda. Questo ti dà la possibilità di cambiare ogni colore in modo indipendente. **Avrai notato che il valore d'uscita della fotoresistenza non copre tutto l'intervallo da 0 a 1023. Per questo progetto va bene, ma per una spiegazione più dettagliata di come calibrare l'intervallo effettivo, vedi il Progetto 06.** ![Lente](lente.png) > *Probabilmente hai notato che la sfumatura dei LED non è lineare. Quando il LED è circa a metà luminosità, sembra che non diventi più luminoso. Questo perché i nostri occhi non percepiscono la luminosità in maniera lineare. La luminosità del LED dipende non solo dal livello di `analogWrite()`, ma anche dalla distanza della luce dal diffusore, la distanza dell'occhio dalla luce e la luminosità della luce rispetto al resto della luce nella stanza.* ![Cervello](cervello.png) > *Come puoi usarla per sapere se fuori è una bella giornata mentre stai lavorando in casa? Quali altri tipi di sensori puoi utilizzare per controllare il colore del LED?* ![Forbici e colla](forbici-colla.png) > Il LED per sé è abbastanza carino, ma non è una vera lampada. Tuttavia, ci sono vari modi per diffondere la luce e a farla somigliare a una lampadina tradizionale a incandescenza. Per esempio, una pallina da ping pong con un foro per il LED può diventare un bel diffusore. Altre possibilità sono quelle di coprire la luce con colla traslucida o levigare la superficie del LED. Non importa quale opzione scegli, si perderà almeno un po' di luminosità quando è diffusa, ma probabilmente sarà molto più gradevole. **Non più limitato al solo accendere e spegnere luci, ora hai il controllo sulla luminosità. `analogWrite()` è la funzione che ti permette di comandare in PWM i componenti collegati ai piedini 3, 5, 6, 9, 10, 11, variando il ciclo di lavoro.** ![Diffusore palla da ping pong](04-immagine_ping_pong.png) ### CODICE COMPLETO ```cpp /* Arduino Starter Kit example Project 4 - Color Mixing Lamp This sketch is written to accompany Project 3 in the Arduino Starter Kit Parts required: - one RGB LED - three 10 kilohm resistors - three 220 ohm resistors - three photoresistors - red green and blue colored gels created 13 Sep 2012 modified 14 Nov 2012 by Scott Fitzgerald Thanks to Federico Vanzati for improvements https://store.arduino.cc/genuino-starter-kit This example code is part of the public domain. */ const int greenLEDPin = 9; // LED connected to digital pin 9 const int redLEDPin = 10; // LED connected to digital pin 10 const int blueLEDPin = 11; // LED connected to digital pin 11 const int redSensorPin = A0; // pin with the photoresistor with the red gel const int greenSensorPin = A1; // pin with the photoresistor with the green gel const int blueSensorPin = A2; // pin with the photoresistor with the blue gel int redValue = 0; // value to write to the red LED int greenValue = 0; // value to write to the green LED int blueValue = 0; // value to write to the blue LED int redSensorValue = 0; // variable to hold the value from the red sensor int greenSensorValue = 0; // variable to hold the value from the green sensor int blueSensorValue = 0; // variable to hold the value from the blue sensor void setup() { // initialize serial communications at 9600 bps: Serial.begin(9600); // set the digital pins as outputs pinMode(greenLEDPin, OUTPUT); pinMode(redLEDPin, OUTPUT); pinMode(blueLEDPin, OUTPUT); } void loop() { // Read the sensors first: // read the value from the red-filtered photoresistor: redSensorValue = analogRead(redSensorPin); // give the ADC a moment to settle delay(5); // read the value from the green-filtered photoresistor: greenSensorValue = analogRead(greenSensorPin); // give the ADC a moment to settle delay(5); // read the value from the blue-filtered photoresistor: blueSensorValue = analogRead(blueSensorPin); // print out the values to the Serial Monitor Serial.print("raw sensor Values \t red: "); Serial.print(redSensorValue); Serial.print("\t green: "); Serial.print(greenSensorValue); Serial.print("\t Blue: "); Serial.println(blueSensorValue); /* In order to use the values from the sensor for the LED, you need to do some math. The ADC provides a 10-bit number, but analogWrite() uses 8 bits. You'll want to divide your sensor readings by 4 to keep them in range of the output. */ redValue = redSensorValue / 4; greenValue = greenSensorValue / 4; blueValue = blueSensorValue / 4; // print out the mapped values Serial.print("Mapped sensor Values \t red: "); Serial.print(redValue); Serial.print("\t green: "); Serial.print(greenValue); Serial.print("\t Blue: "); Serial.println(blueValue); /* Now that you have a usable value, it's time to PWM the LED. */ analogWrite(redLEDPin, redValue); analogWrite(greenLEDPin, greenValue); analogWrite(blueLEDPin, blueValue); } ```