An Arduino library to control LEDs. It uses a non-blocking approach and can control LEDs in simple (on/off) and complex (blinking, breathing) ways in a time-driven manner.
JLed got some coverage on Hackaday and someone did a video tutorial for JLed - Thanks!
// blink and breathe two LEDs (builtin and gpio 9) for 12 seconds.
#include <jled.h>
JLed led_breathe = JLed(9).Breathe(1500).Repeat(6).DelayAfter(500);
JLed led_blink = JLed(LED_BUILTIN).Blink(500, 500).Repeat(11).DelayBefore(1000);
void setup() { }
void loop() {
led_blink.Update();
led_breathe.Update();
}
- Features
- Installation
- Usage
- Parameter overview
- Platform notes
- Example sketches
- Unit tests
- Contributing
- Author
- License
- non-blocking
- simple on/off
- breathe effect
- blinking effect
- fade-on and -off effect
- user provided effects
- supports reversed polarity of LED
- easy configuration using fluent interface
- Arduino, ESP8266 and ESP32 platform compatible
In the main menu of the Arduino IDE, select Sketch
> Include Library
>
Manage Libraries...
and search for jled
, then press install
.
Add jled
to your library dependencies in your platformio.ini
project file,
e.g.
...
[env:nanoatmega328]
platform = atmelavr
board = nanoatmega328
framework = arduino
lib_deps=jled
...
First the LED object is constructed and configured, then the state is updated
with subsequent calls to the Update()
method, typically from the loop()
function. While the effect is active, Update
returns true
, otherwise
false.
The constructor takes the pin, to which the LED is connected to as
only parameter. Further configuration of the LED object is done using a fluent
interface, e.g. JLed led = JLed(13).Breathe(2000).DelayAfter(1000).Repeat(5)
.
See examples and Parameter overview section below for
further details.
Calling On()
turns the LED on on after an optional time, specified by
DelayBefore()
, has elapsed. To immediately turn a LED on, make a call
like JLed(LED_BUILTIN).On().Update()
.
#include <jled.h>
// turn builtin LED on after 1 second.
JLed led = JLed(LED_BUILTIN).On().DelayBefore(1000);
void setup() { }
void loop() {
led.Update();
}
Off()
works like On()
, except that it turns the LED off.
In blinking mode, the LED cycles through a given number of on-off cycles.
#include <jled.h>
// blink internal LED every second.
JLed led = JLed(LED_BUILTIN).Blink(1000, 1000).Forever();
void setup() { }
void loop() {
led.Update();
}
In breathing mode, the LED smoothly changes brightness using PWM.
#include <jled.h>
// connect LED to pin 13 (PWM capable). LED will breathe with period of
// 2000ms and a delay of 1000ms after each period.
JLed led = JLed(13).Breathe(2000).DelayAfter(1000).Forever();
void setup() { }
void loop() {
led.Update();
}
In FadeOn mode, the LED is smoothly faded on to 100% brightness using PWM.
#include <jled.h>
// LED is connected to pin 9 (PWM capable) gpio
JLed led = JLed(9).FadeOn(1000).DelayBefore(2000);
void setup() { }
void loop() {
led.Update();
}
In FadeOff mode, the LED is smoothly faded off using PWM. The fade starts at 100% brightness. Internally it is implemented as a mirrored version of the FadeOn function, i.e. FadeOn(t) = FadeOff(period-t)
It is also possible to provide a user defined brightness function. The
signature of such a function is unit8_t func(unit32_t t, uint16_t period, uintptr_t param)
.
The function must return the brightness in range 0..255 in dependence of the
current time t.
The example uses a user provided function to calculate the brightness.
#include <jled.h>
// this function returns changes between 0 and 255 and vice versa every 250 ms.
uint8_t blinkFunc(uint32_t t, uint16_t /*period*/, uintptr_t /*param*/) {
return 255*((t/250)%2);
}
// Run blinkUserFunc for 5000ms
JLed led = JLed(LED_BUILTIN).UserFunc(blinkFunc, 5000);
void setup() {
}
void loop() {
led.Update();
}
Call Stop()
to immediately turn the LED off and stop any running effects.
The following table shows the applicability of the various parameters in dependence of the chosen effect:
Method | Description | Default | On | Off | Blink | Breath | FadeOn | FadeOff | UserFunc |
---|---|---|---|---|---|---|---|---|---|
DelayBefore(t) | time to wait before state is initially changed | 0 | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
DelayAfter(t) | time to wait after each period | 0 | Yes | Yes | Yes | Yes | |||
Repeat(n) | repeat effect for given number of periods | 1 | Yes | Yes | Yes | Yes | Yes | ||
Forever() | repeat infinitely | false | Yes | Yes | Yes | Yes | Yes | ||
LowActive() | set output to be low-active (i.e. invert output) | false | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
- all times are specified in milliseconds
- time specified by
DelayBefore()
is relative to first invocation ofUpdate()
The DAC of the ESP8266 operates with 10 bits, every value JLed writes out gets automatically scaled to 10 bits, since JLed internally only uses 8 bits. The scaling methods makes sure that min/max relationships are preserved, i.e. 0 is mapped to 0 and 255 is mapped to 1023. When using a user defined brightness function on the ESP8266, 8 bit values must be returned, all scaling is done by JLed transparently for the application, yielding platform independent code.
The ESP32 Arduino SDK does not provide an analogWrite()
function. To
be able to use PWM, we use the ledc
functions of the ESP32 SDK.
(See esspressif documentation for details).
The ledc
API connects so called channels to GPIO pins, enabling them to use
PWM. There are 16 channels available. Unless otherwise specified, JLed
automatically picks the next free channel, starting with channel 0 and wrapping
over after channel 15. To manually specify a channel, the JLed object must be
constructed this way:
JLed esp32Led = JLed(Esp32AnalogWriter(2, 7)).Blink(1000, 1000).Forever();
The Esp32AnalogWriter(pin, chan)
constructor takes the pin number as the
first argument and the channel number on second position. Note that using the
above mentioned constructor yields non-platform independent code.
Examples sketches are provided in the examples directory.
To build an example using the PlatformIO ide, simply uncomment the example to be built in the platformio.ini project file, e.g.:
...
[platformio]
; uncomment example to build
src_dir = examples/hello
;src_dir = examples/breathe
...
To build an example sketch in the Arduino IDE, simply select an example from
the File
> Examples
> JLed
menu.
Jled comes with an exhaustive host based unit test suite. Info on how to run the host based provided unit tests is provided here.
- fork this repository
- create your feature branch
- add code
- add unit test(s)
- add documentation
- make sure linter does not report problems (make lint)
- commit changes
- submit a PR
Jan Delgado, jdelgado[at]gmx.net.