A chi non è capitato almeno una volta di notare quel bellissimo effetto led presente su alcuni dispositivi elettronici, il cosiddetto breathing led ovvero “led che respira”?
In rete ci sono makers da ogni parte del mondo che muniti di oscilloscopio hanno provato a fare reverse engingering per riprodurre l’algoritmo in questione e trasformarlo in uno sketch per Arduino.
Il problema sta nel fatto che la maggior parte dei codici trovati in rete hanno due difetti: il primo è che tali algoritmi non contengono una funzione ma una serie di valori precalcolati che non rendono continuato e preciso l’effetto, mentre il secondo risiede nel fatto che spesso questi codici sono bloccanti, ovvero fanno uso di delay e non permettono quindi la corretta continuazione del restante codice all’interno dello sketch.
Prendendo spunto dal codice pubblicato da Sean Voisen che ha trovato la funzione che definisce i valori PWM per pilotare il led, ho fatto delle modifiche e dei test per renderlo non bloccante, ovvero per farlo lavorare in background e permettere l’esecuzione di altro codice.
Il risultato finale è il seguente:
Il collegamento avviene ovviamente come per qualsiasi altro led e il sistema è in grado di pilotare anche led di potenza o led strip, tramite opportuno transistor o mosfet (Vedi: Pilotare una led strip con Arduino)
Il codice per Arduino è il seguente:
/* NonBlockingBreathingLed 0.1 by Luca Soltoggio - 2015 12 May 2015 http://www.arduinoelettronica.com/ http://arduinoelectronics.wordpress.com/ http://minibianpi.wodpress.com/ Use a exp + sin function to recreate a non-blocking breathing led effect Released under GPL v.2 license */ #include <math.h> #define ledPin 11 int i=0; int breathe_delay = 15; // delay between loops unsigned long breathe_time = millis(); void setup() { } void loop() { nonBlockingBreath(); // call the nonblocking function // yourOtherCodeHere(); } void nonBlockingBreath() { if( (breathe_time + breathe_delay) < millis() ){ breathe_time = millis(); float val = (exp(sin(i/2000.0*PI*10)) - 0.36787944)*108.0; // this is the math function recreating the effect analogWrite(ledPin, val); // PWM i=i+1; } }
Buon divertimento!!! 🙂