The Noiasca Tool Kit for LEDs
The Noiasca Tool Kit contains several classes: It all starts with helpers to let LEDs blink, dim, flicker and several other effects in parallel without the usage of any delay. Furthermore the tool kit contains a class to read and debounce a button click very easily. Finally, the tool kit brings timers, which can be used to start and stop actions. For example if you want to start a blinking LED on button press and let it blink for 10 seconds, just combine a blink LED, the button and a timer from the Noiasca Tool Kit.
The Noiasca Tool Kit contains several classes for different style of LEDs. Each kind of pattern is explained here. Furthermore you are not limited to use the Arduino pins only, you can use this classes also for your WS2812 Neopixels and other driver ICs.
On this page only the LED classes are explained in detail, but you will find a lot of examples for buttons and timer in the library examples.
The Effects
Blink
This is a simple class to "blink" a LED. You can define the on and the off interval separately.
A very simple sketch to blink without delay will look like following:
#include <Noiasca_led.h> #include <utility/Noiasca_discrete.h> BlinkPin blinkLed {13}; // declare one blinking LED and assign pin 13 void setup() { blinkLed.begin(); // you have to call the .begin() method for this LED //blinkLed.setInterval(700, 300); // optional: you can define the ON and OFF times in milliseconds blinkLed.on(); // switch the blinking on } void loop() { blinkLed.update(); // call the update function in loop() to refresh the LED // put other non blocking code here, to run repeatedly }
You need two #includes:
The library with the effects/patterns and the hardware interface. As we are using
the pin 13 on the Arduino, we have to include the hardware interface for
"discrete Arduino pins".
The constructor makes one blinking LED available on pin 13.
.begin() : The begin() must be called in setup(). It will do all hardware specific tasks. In the case of the blink LED it will set the pinMode to OUTPUT.
.on() will switch the blink effect on.
.update() will do all the magic behind the scenes. It works similar to "Blink without Delay". The class has it's own time management and will switch the pin on or off if it is needed.
There are several other member functions available for the blink LED:
.off() will switch off the effect - the LED will get dark.
.toggle() will either switch the effect on or off. This member function comes very handy when you have a single push button and if you want to switch the blinking on or off with each button press.
.setOnInterval(interval) and .setOffInterval(interval) with these member function you can define the on and off times. The default values are 500ms which give you a consistent blinking. If you want a flashing effect, you can make the one interval time longer than the other:
blinkLed.setOnInterval(700); // 700ms on blinkLed.setOffInterval(300); // 300ms off
Alternating
"Alternating" is the blinking of two LEDs vice versa. Either the first or the second LED is on. The constructor of an alternating LED pair needs two pins:
AlternatingPin alternatingLed {2, 4};
Bounce5
"Bounce 5" is a LED pattern, with 5 LEDs: Only one LED is on and the other LEDs will be off. This gives an effect of a running LED between left and right. You can compare the effect with the KITT/Larson Scanner. The constructor for this effect needs 5 pins:
Bounce5Pin bounce5led {2, 3, 4, 5, 6};
Flicker
This effect simulates a "flickering" light like a fire. The pattern is random and you will get an even better effect if you start flicker with two LEDs for example a red and a yellow LED. The effect should run on a PWM enabled pin:
FlickerPin flickerLed {3}; // UNO PWM pins 3, 5, 6, 9, 10, 11
Fluorescent
"Fluorescent" tubes tend to start a little delayed. There might occure a short flicker effect on start up. And it will take a short time till the fluorescent tube (or lamp) will shine in full 100% intensity. You can simulate this effect with a LED. Use a PWM enabled pin for the best effect.
FluorescentPin fluorescentLed {3}; // UNO PWM pins 3, 5, 6, 9, 10, 11
Heartbeat
A "heartbeat" LED will dim up and down permanently.
HeartbeatPin heartbeatLed {3}; // UNO PWM pins 3, 5, 6, 9, 10, 11
You can define thresholds for the minimum and maximum dim level.
.setInterval(10) will effect the speed of the dimming. Default value
is 50.
.setMinBrightness(50) this will limit the lower end of the dimm range.
Default value is 0 - meaning the LED will switch off.
.setMaxBrightness(240) this will limit the maximum brightness. Default
value is 255. Highest value on an Arduino is 255.
Pulse (monoflop)
(click to see the effect)
A "pulse" is an high output for a (short) period of time which will return to low. It acts like a monoflop. A pulse turns on a LED for a defined period of time without using the delay() function. This means that other code can run at the same time without being interrupted by the LED code. The output acts like a monoflop.
PulsePin pulseLed {13}; // any output pin
You are not limited to LEDs. You can use this also to pulse a relay for a specific time. If your relay (or relay module) is LOW active, you can set the optional second parameter to indicate a LOW active output:
PulsePin pulseLed {13, LOW}; // if the pin should be LOW active, set second parameter
Rhythm
A "rhythm" LED can be set up to "blink" in a specific pattern. The rhythm LED supports 1 to 4 pairs of on/off times. This can be used for police cars, ambulances and similar vehicles. The default sequence is ECE2 (150, 60, 20, 270). But you can set any other sequence also (ECE1, HELLA 3, HELLA 4,...) . Just remember that you have to define the pattern in pairs of on and off times.
RhythmPin rhythmLed {13}; // declare LED and assign pin
To set the blink pattern/rhythm you have to hand over the on and off times in pairs. Up to 4 pairs (=8 values) are possible.
rhythmLed.setInterval(40, 40, 40, 40, 40, 40, 40, 220); // HELLA 4 rhythmLed.setInterval(25, 25, 25, 25, 25, 375); // HELLA 3 rhythmLed.setInterval(150, 60, 20, 270); // ECE 2 --> default rhythmLed.setInterval(180, 320); // ECE 1 ON = 180ms, OFF = 320ms
Obviously, the variant with 180, 320 could be achieved as "BlinkLed" also.
Smooth
On PWM pins you can use a smooth dim up / down for a LED. When you switch the LED on, the LED will get brighter time by time. If you switch it off, it will slowly dimm down.
SmoothPin smoothLed {3}; // UNO PWM pins 3, 5, 6, 9, 10, 11
you can limit the maximum PWM value with following member function:
smoothLed.setMaxBrightness(240); // you can limit the maximum brightness. Highest value on Arduino is 255. Default 255.
The inverse function to retrieve the current brightness is:
uint16_t currentBrightness = smoothLed.getCurrentBrightness();
Effect
If you need a LED with several effects you can use EffectPin. It combines all described effects on a single output and you can change the effect during runtime.
Trafficlight
A traffic light consist of up to 3 LEDs (red, yellow, green) and can have several faces to be shown
states of a traffic light 0 OFF // no LED is on 1 RED 2 REDYELLOW // the RED and the Yellow are on 3 GREEN 4 YELLOW 5 YELLOWBLINK // the traffic light is blinking yellow 6 GREENBLINK // like used in Austria or Ukraine
Turn signal
The turn signals for a car consists of 2 side markers (for left and right) and an optional hazard warning light in the dashboard.
TurnsignalPin turnsignalPin{2, 3, 4}; // GPIO left, GPIO right, GPIO hazard warning light (optional)
You can switch the turn signal to LEFT, RIGHT and HAZARD. In case of HAZARD, the left and the right LED are blinking in sync. Additionally, the hazard LED for the dashboard indicates the status.
The Hardware Interfaces
The described LED effects are not limited to discrete Arduino pins. You can combine these effects also with several other ICs. Currently the library comes with following HW drivers
- Discrete Arduino pins (like described in each effect example above)
- Neopixel (WS2811/WS21812 family) with the Adafruit Neopixel
- Neopixel (WS2811/WS21812 family) with the FastLed Library
- HOLTEK HT16K33
- PWM Servo Driver PCA9685
- Portexpander PCF8574
And you even can write your own HW driver and combine it with the existing effects.
Neopixel WS2812 with Adafruit Neopixel
If you are running out of pins for your LEDs, you could use a strip with Neopixel / WS2812/ APA106 and add a lot of single effects. You can even mix discrete LEDs (connected to an Arduino PIN) and Neopixels in one sketch and run the same effect on different LED hardware. Obviously Neopixel can also be used with different colors. All classes are available with "Pixel":
AlternatingPixel BlinkPixel Bounce5Pixel FlickerPixel FluorescentPixel HeartbeatPixel OnOffPixel PulsePixel RhythmPixel SmoothPixel TrafficlightPixel TurnsignalPixel
On hardware level the library relies on the "Adafruit Neopixel" library. Declare your strip handover the pixel you want to be effected:
#include <Noiasca_led.h> // This library #include <utility/Noiasca_neopixel.h> // the hardware interface for Neopixel #include <Adafruit_NeoPixel.h> // use the Adafruit library for Neopixel constexpr uint16_t pixelCount = 32; // the size of your strip constexpr byte pixelPin = 8; // the pin you have connected your Neopixel strip Adafruit_NeoPixel strip(pixelCount, pixelPin, NEO_GRB + NEO_KHZ800); // define your strip BlinkPixel blinkPixelA(strip, 0); // a blink LED on a Neopixel strip using pixel 0
Neopixel WS2812 with FastLED library
When you prefer the FastLED library - there are also examples which uses the FastLED library. The FastLED classed are named:
AlternatingFastLED BlinkFastLED Bounce5FastLED FlickerFastLED FluorescentFastLED HeartbeatFastLED OnOffFastLED PulseFastLED RhythmFastLED SmoothFastLED TrafficlightFastLED TurnsignalFastLED
The LED Driver HOLTEK HT16K33 (Version 0.3.0 upwards)
The HT16K33 is a LED driver for I2C. The LEDs can be arranged in a matrix with 8 common cathodes and 16 common anodes. A total of 128 LEDs can be driven by this IC.
All described effects can be used with the HT16K33. But keep in mind, that the HT16K33 has no PWM outputs. So only the simple effects (blink, pulse, bounce5, traffic lights,...) will work as intended.
The library contains a simple class for the HT16K33 driver. First you create an instance of the driver. When you create the effect LED, you hand over the driver object and a "pixel" which is one of the LED 0 to 127.
A minimal example for the HT16K33 looks like following:
#include <Wire.h> // I2C class for the port expander #include <Noiasca_led.h> // download from: https://werner.rothschopf.net/microcontroller/202202_tools_led_en.htm #include <utility/Noiasca_HT16K33.h> // needed to control HT16K33 - part of the LED tool kit // create a expander object HT16K33expander myHT16K33(0x70); // create an expander instance at a specific I2C address (usually between 0x70 - 0x77) // create your LED objects // hand over the expander object and the number of LED (0..127) BlinkHT16K33 blinkLEDA(myHT16K33, 0 + 0); // a blink LED on a port expander (first cathode, first Anode) void setup() { Wire.begin(); // needed for the HT16K33 myHT16K33.begin(); // start the HT16K33 object blinkLEDA.begin(); // start the LED object blinkLEDA.setOnInterval(250); // set the on time of a pin } void loop() { blinkLEDA.update(); // call .update() for your object }
The PWM Servo Driver PCA9685 (Version 0.1.0 upwards)
The PCA9685 is often used as PWM or Servo driver. The Noiasca Toolkit can be used to get all effects on the 16 outputs of the PCA9685. Just create a driver object ("pwm") with the Adafruit library and hand over this object and the pin number to an effect class with PCA9685.
AlternatingPCA9685 BlinkPCA9685 Bounce5PCA9685 FlickerPCA9685 FluorescentPCA9685 HeartbeatPCA9685 OnOffPCA9685 PulsePCA9685 RhythmPCA9685 SmoothPCA9685 TrafficlightPCA9685 TurnsignalPCA9685
On hardware level the library relies on the "Adafruit PWM Servo" library. Declare your PCA9685 device and handover the pin you want to be effected:
#include <Noiasca_led.h> // the library with the LED effects #include <utility/Noiasca_PCA9685.h> // needed for PWM Servo Driver #include <Wire.h> // I2C library for the PCA9685 #include <Adafruit_PWMServoDriver.h> // install with Library Manager Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); // create a pwm instance / a PCA9685 object HeartbeatPCA9685 heartbeatLed {pwm, 1}; // one pin on your PCA9685 object
The Portexpander PCF8574
The portexpander PCF8574 can be used for simple on/off effects like blink LED or to pulse a relay. Effects which need PWM don't work nicely with the PCF8574. For these effects I recommend to use another port expander.
AlternatingPCF8574 BlinkPCF8574 Bounce5PCF8547 EffectPCF8547 FlickerPCF8547 // @note the PCF8547 is on/off only - no PWM. The effect will be limited. FluorescentPCF8547 // @note the PCF8547 is on/off only - no PWM. The effect will be limited. HeartbeatPCF8547 // @note the PCF8547 is on/off only - no PWM. The effect will be limited. OnOffPCF8547 PulsePCF8547 RhythmPCF8547 SmoothPCF8547 // @note the PCF8547 is on/off only - no PWM. The effect will be limited. TrafficlightPCF8547 TurnsignalPCF8547
Don't forget, the PCF8574 comes in two variants with addresses from either 0x20 - 0x27 or 0x38 - 0x3F.
Other functions (Buttons, Timer)
The Noiasca Toolkit contains classes to read easily buttons (momentary switches) and a simple timer to trigger events in your sketch. See the examples.