Decorazioni e luci per il Presepe: un semplice focolare con alternanza giorno/notte usando Arduino

Arduino dic 12, 2018

Da tempo avevo voglia di smanettare un po' con Arduino, da prima ancora di quando, almeno due anni fa, mi fu regalato quello Starter Kit che non sono mai riuscito ad utilizzare se non per vedere cosa contenesse.

Quale occasione migliore del Natale, con tutte le sue luci e le sue decorazioni, per iniziare a fare qualcosina di concreto? Ed ecco quindi un piccolo esperimento di illuminazione "multipla" del Presepe, che oltre ad essere semplice (so molto poco di elettronica) è anche un esercizio nel far fare ad Arduino più cose insieme senza multi-threading.

L'idea è semplice, e prende spunto da due progetti trovati in giro:

Quello che volevo fare inizialmente era avere un piccolo fuocherello che illuminasse il presepe al posto delle solite luci colorate, e quando mi sono imbattuto in quei due progetti ho voluto arricchire tutto con una simulazione del ritmo giorno/notte per dare completezza alla scena.

La problematica principale è che Arduino UNO, quello che ho a disposizione, non è multithread - ed è pure pessimo nel tenere il tempo in quanto si basa su un oscillatore ceramico e non al quarzo (ci sono arrivato dopo aver imprecato non poco con i millisecondi), per cui ho dovuto usare uno stratagemma per far andare insieme i due "sistemi", non potendo usare il classico delay().

Il focolare viene gestito tenendo conto dei millisecondi trascorsi (recuperati con la funzione `millis()`) ed usando un intervallo casuale, così da dare l'idea generale di tremolìo delle fiamme; anche la luminosità di ogni LED non è fissa ma varia in un range random di valori, come una fiamma che sia alza e si abbassa:

void manageFire()
{
  int yellow_brigthtness = 0;
  int red_brightness = random(20,200);
  if (random(0,9) > 2) {
    yellow_brightness = random(120);
  }
  analogWrite(FUOCO_ROSSO, red_brightness);
  analogWrite(FUOCO_GIALLO, yellow_brightness);
}

L'alternanza giorno/notte, invece, si basa un semplice contatore di secondi (sempre grazie a `millis()`)  che, in base alle durate specificate nell'array `durations`, fa accendere e spegnere in sequenza i LED che rappresentano le fasi della giornata:

 if (seconds <= durations[0]) {
   light_sunrise = fadeIn(light_sunrise, step);
   // in sequenza: alba, giorno, tramonto, notte, stelle
   manageDay(light_sunrise,0,0,0,0);
 }
 
 if (seconds > durations[0] && seconds <= durations[1]) {
   light_sunrise = fadeOut(light_sunrise, step);
   light_day = fadeIn(light_day, step);
   manageDay(light_sunrise, light_day ,0,0,0);
 }
 
 if (seconds > durations[1] && seconds <= durations[2]) {
   light_sunset = fadeIn(light_sunset, step);
   light_day = fadeOut(light_day, step);
   manageDay(0,light_day,light_sunset,0,0);    
 }
 
 if (seconds > durations[2] && durations <= durations[3]) {
   light_sunset = fadeOut(light_sunset, step);
   // il lED per la notte è sull'uscita digitale e non analogica
   // per il semplice motivo che era erano finite :)
   manageDay(0,0,light_sunset,HIGH,random(40,150));
 }

A corredo ti tutto ciò alcune funzioni che gestiscono con più comodità la sequenza di accensioni ( manageDay()) e l'incremento/decremento progressivo della luminosità dei LED ( fadeIn(), fadeOut()).

Pochi componenti, uno sketch semplice e un effetto complessivo piacevole: insomma, un progetto ideale per i primi passi con Arduino, spero di avere il tempo di dedicarmi a qualcosa di più impegnativo e complesso.

Matteo Vignoli

Sviluppatore Web Full-Stack, autodidatta, curioso per natura, attualmente impiegato a Milano in ContactLab