Dissolvenza di un led con Arduino e PWM

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

Pin digitali PWM di Arduino
Pin digitali PWM di Arduino

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.

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.