In un precedente articolo abbiamo fatto accendere la luce di un led con Arduino, utilizzando la funzione digitalWrite a cui passavamo, oltre al pin digitale del led, le costanti HIGH e LOW, per applicare al pin rispettivamente 5 V e 0 V di tensione. In questo modo il led può avere solo due stati, acceso e spento, senza alcuna gradazione nei livelli di luminosità.
Quando abbiamo provato a pilotare in led rgb per mescolare i livelli di rosso, verde e blu per creare luce di diverso colore, abbiamo visto però che è possibile passare valori intermedi a un pin analogico tramite la funzione analogWrite.
Adesso vedremo come accendere e spegnere un led con effetto dissolvenza servendoci dei pin digitali PWM (Pulse-Width Modulation) di Arduino e usando ancora la funzione analogWrite.
Cos’è la modulazione PWM
Arduino presenta alcuni pin digitali (3, 5, 6, 10, 11) contrassegnati con il carattere tilde (~) con i quali mette a disposizione dello sviluppatore una particolare funzionalità del microcontroller ATMega definita PWM (Pulse-Width Modulation o mudulazione di larghezza di impulso). Tramite questa modulazione un pin digitale viene commutato da 0 a 5 V, cambiando le proporzioni di tempo (in gergo duty-cycle) in cui il pin rimane in stato di HIGH o LOW. La variazione della durata della larghezza di impulso prende il nome di pulse width ed è sostanzialmente il fattore con cui si altera l’intervallo temporale in cui l’impulso digitale è in stato di ON o di OFF. Con un 25% di duty-cycle sul pin digitale scorrono 5 V per un quarto del tempo; con il 75% per tre quarti del tempo ecc. Con valori di duty-cycle vicini al 100% il pin è sempre a on, viceversa con valori vicino allo 0% il pin è sempre a off. L’alterazione del fattore temporale verrà ottenuta pilotando un pin pwm di Arduino tramite output analogici.
A questo punto ci si potrà chiedere come mai non si utilizzino i pin analogici per impostare dei duty-cycle che causino la variazione di intensità della luce del led, oppure perché non si utilizzino digitalWrite e delay in combinazione. Il fatto è che nel caso in cui si debbano controllare molteplici pin digitali, il microcontrollore dovrà occuparsi di più operazioni e non sarà in grado di operare ad una rapidità tale da ingannare l’occhio umano, causando più che altro un effetto di lampeggiamento.
Lo sketch di esempio e le funzioni accendi e spegni
Per il progetto di esempio di questo articolo non faremo altro che servirci del circuito già utilizzato per accendere un led e di cui modificheremo lo sketch per cambiare il pin digitale di riferimento e aggiungere un paio di funzioni. Per la lista dei componenti fate riferimento a questo link.
La funzione accendi
La funzione accendi con cui aumenteremo gradatamente la luminosità del led, eseguirà un ciclo utilizzando un contatore che verrà incrementato di un’unità, partendo da 0 per arrivare a 255.
void accendi() {
for(int i=0; i<255; i++) {
analogWrite(LED_PIN, i);
delay(30);
}
}
All’interno del ciclo utilizziamo analogWrite sul pin digitale per creare l’effetto di una variazione continua di valori, mentre in realtà stiamo solo accendendo e spegnendo il led in rapida successione. Aspettiamo 30 millisecondi prima di passare alla prossima iterazione del ciclo for per fare in modo che la dissolvenza sia percepibile
Provate a variare il valore del delay per verificare velocità e percepibilità dell’effetto dissolvenza della luce del led.
La funzione spegni
In maniera speculare alla funzione accendi, la funzione spegni esegue un ciclo a ritroso, partendo da 255 e decrementando di un’unità fino a 0, per creare un effetto di dissolvenza durante lo spegnimento del led.
void spegni() {
// wait for a second
for(int i=254; i>=0; i--) {
analogWrite(LED_PIN, i);
delay(30);
}
}
Lo sketch completo
Ecco l’intero listato per testare la modulazione PWM con Arduino
#define LED_PIN 11
// the setup function runs once when you press reset or power the board
void setup() {
Serial.begin(9600);
pinMode(LED_PIN, OUTPUT);
}
void accendi() {
for(int i=0; i<255; i++) {
analogWrite(LED_PIN, i);
delay(30);
}
}
void spegni() {
// wait for a second
for(int i=254; i>=0; i--) {
analogWrite(LED_PIN, i);
delay(30);
}
}
// the loop function runs over and over again forever
void loop() {
// put your main code here, to run repeatedly:
if(Serial.available())
{
int stato = Serial.read();
switch(stato)
{
case 'A':
Serial.println("Avvio dissolvenza di accensione");
accendi();
Serial.println("Led acceso");
break;
case 'S':
Serial.println("Avvio dissolvenza di spegnimento");
spegni();
Serial.println("Led spento");
break;
default:
Serial.println("Comando non riconosciuto");
break;
}
delay(300);
}
}
All’inizio del codice sorgente viene definita la costante LED_PIN associata al pin 11 pwm di Arduino. Successivamente, nella funzione setup, impostiamo il baud rate per la comunicazione seriale e il pin in modalità OUTPUT.
Nel loop di Arduino, verifichiamo il valore di input sul monitor seriale, in base al quale viene chiamata la funzione accendi o la funzione spegni.
Provate a modificare allo stesso modo il codice dello sketch per gestire il led rgb creando un effetto dissolvenza.
Conclusione
In questo articolo abbiamo visto come sia facile con Arduino e i pin digitali PWM che ci mette a disposizione, accendere e spegnere con gradualità un led, creando un effetto dissolvenza. Abbiamo esaminato in cosa consiste la tecnica di modulazione di larghezza di impulso e come sia in grado di ingannare l’occhio umano variando l’intervallo in cui un pin digitale resta in stato di ON o di OFF. Infine abbiamo approntato una modifica allo sketch di accensione del led visto in un precedente articolo, per utilizzare la modulazione PWM.