The simple LED fading demos are great for learning Arduino, but when you actually need your processor to be doing something — like receiving serial input or reading a sensor — fading your LEDS can get in the way.
Traditional Example
Here’s how LED fading usually works:
void loop() { analogWrite(led, brightness); brightness = brightness + fadeAmount; if (brightness == 0 || brightness == 255) { fadeAmount = -fadeAmount ; } delay(30); }
The problem is in that 30 millisecond delay. This stops your entire program for 30 milliseconds. If you want a slower fade, you have to set it to a higher value and a longer pause. If you’re fading multiple LEDs at different rates, the arduino ends up being paused more time than it’s processing. Which means it’s hard to do anything besides fade a bunch of LEDs.
Introducing LED Fader
LEDFader is a library I wrote while trying to individually fade 4 strips of RGB LEDs on an arduino mega — effectively controlling the PWM on 12 pins independently — while interfacing with a ultrasonic range sensor and an IR receiver.
This library works by tracking the current time adjusts the brightness of each LED accordingly without pausing.
Here’s a simple example:
#include <LEDFader.h> // Create new LED Fader on pin 3 LEDFader led = LEDFader(3); void setup() { // Fade from 0 - 255 in 3 seconds led.set_value(0); led.fade(255, 3000); } void loop() { led.update(); }
This will fade an LED attached to arduino pin 3 from 0 – 255 (full brightness) in 3 seconds without pausing your program at all.
Here’s a more complex example that will fade 6 LEDs to random intensities (between 100 – 255) at random durations (between 1 – 2 seconds):
#include <LEDFader.h> #define LED_NUM 6 // 6 LEDs (perhaps 2 RGB LEDs) LEDFader leds[LED_NUM] = { LEDFader(3), LEDFader(5), LEDFader(6), LEDFader(9), LEDFader(10), LEDFader(11) }; void setup() { } void loop() { // Update all LEDs and start new fades if any are done for (byte i = 0; i < LED_NUM; i++) { LEDFader *led = &leds[i]; led->update(); // This LED is not fading, start a new fade if (led->is_fading() == false) { int duration = random(1000, 3000); // between 1 - 3 seconds // Fade Up if (led->get_value() == 0) { byte intensity = random(100, 255); led.fade(intensity, duration); } // Fade Down else { led.fade(0, duration); } } } }
Even though this is managing 6 LEDs, the call to update()
takes almost no time at all.
How it works
Each time the update()
method is called, as long as a minimum time has passed since the last call, it figures out how far along the fade should be and adjust the PWM value accordingly.
For example, if we’re fading from 0 – 255 in 1 second, and for some reason the first update()
call happens in 500 milliseconds, it will increase the PWM by 128, instead of 1, because we are 50% through the total duration (255 / 2 = 127.5).
Where to git it
You can grab the library from github and feel free to make contributions.