Easy method to flash LEDs

Gaztech

Member
Hi guys,

This could be useful to anyone struggling with getting LEDs to flash.

Using the conventional methods to set up a method which is non-blocking to the main program you end up with loads of code using millis() and elapsedMillis() and it isn't easy to read or even work out what is going on. I needed to flash individual LEDs for a project depending on which button was selected. Using the conventional methods the code quickly became very large and out of hand. I can't believe just how difficult it is to code it up!

There is an easier way to do it by using the PinFlasher class by Forward Computing in Oz.

Go here for more info:

https://www.forward.com.au/pfod/ArduinoProgramming/TimingDelaysInArduino.html

To use it, you must install the SafeString library to the Arduino IDE as PinFlasher is part of that. Once installed you will need to add #include <PinFlasher.h> to use it.

It does have some quirks though which can be frustrating and there are some things about it that are not explained very well in the original documentation. The purpose of this quick post is to explain these oddities with an example so that you can use it straight away. It's deceptively simple.

A few points which will catch you out:

Setting it up is easy and you can set separate instances up to control multiple LEDs (see the example code) BUT... although you are setting up separate instances, there is only ONE flash routine so if you have multiple LEDs flashing all at once, stopping one instance seems to stop them all.

The flasher.setOnOff(PIN_OFF) command does stop the timer and the flashing but it does NOT turn off the respective LED! Initially this looks as though it's not working. To turn off the LED, you have to follow the command by a digitalWrite(x, LOW) command. (where x is the LED you wish to turn off).

The documentation states that you cannot have the flasher.setOnOff(xx) command within an IF statement so it's tricky to control the function. I found that this was indeed the case. You also cannot use delay(x) with it at all as it seems to screw it up (why would you - but it's worth knowing).

It appears that the flasher must be called at each loop iteration for proper operation. However, if the setOnOff command is placed right at the TOP of the main program loop I found that you actually can place this command within an IF loop with no adverse consequences. This makes it controllable.

The following code shows how this works. If you take out all the setup routines for the buttons and LEDs, you will see that the code to do the flashing is very simple - much easier than the traditional ways to code it up.

I set up 4 buttons and 2 LEDs for this example.

Button 1, turns on LED1 and it flashes.
Button 2, turns the flashing OFF and extinguishes the LED.
Button 3, turns on LED2 and it flashes.
Button 4, turns the flashing OFF and extinguishes the LED.

It's a very rudimentary piece of code but it clearly shows how to navigate control of the PinFlash function for multiple LEDs. Unlike the delay(x) command, it does not interrupt program execution as it is based on the millisDelay extension.

PHP:
/*  
 *   FLASHER ROUTINE TO FLASH LEDS WITHOUT AFFECTING MAIN LOOP OPERATION
 *   
 *   Routine using 4 buttons and 2 LEDs
 *   ----------------------------------
 *   Pressing button 1 flashes LED1
 *   Pressing button 2 stops LED1 flashing
 *   Pressing button 3 flashes LED2
 *   Pressing button 4 stops LED2 flashing
 *   
 */
 
// Debounce the buttons first 
#include <Bounce.h>
#define BUTTON_DEBOUNCE 100     // 50 = 50 ms debounce
// SELECT buttons 1-4
Bounce button5 = Bounce(5, BUTTON_DEBOUNCE);       // Button 1
Bounce button6 = Bounce(6, BUTTON_DEBOUNCE);       // Button 2 
Bounce button7 = Bounce(7, BUTTON_DEBOUNCE);       // Button 3 
Bounce button8 = Bounce(8, BUTTON_DEBOUNCE);       // Button 4 

// Set up the Flasher routine
#include <PinFlasher.h>
int FlashState = 0;
int flasher_pin1 = 14;
int flasher_pin2 = 16;
PinFlasher flasher1(flasher_pin1);
PinFlasher flasher2(flasher_pin2);

void setup() {
// Configure the pins for footswitch buttons as input mode = pullup resistors.  
  pinMode(5, INPUT_PULLUP);    // Button 1 
  pinMode(6, INPUT_PULLUP);    // Button 2
  pinMode(7, INPUT_PULLUP);    // Button 3
  pinMode(8, INPUT_PULLUP);    // Button 4 

// Set Output pins to drive the LEDs 
// Set Pins 14 and 16 OUTPUT for LEDs   
   pinMode(14, OUTPUT); // set Pin Assignment to OUTPUT for LED1
   pinMode(16, OUTPUT); // set Pin Assignment to OUTPUT for LED3
}
//      Main Loop
void loop() {
  // Test to see which button was last pressed
  if (FlashState == 1) {
  flasher1.setOnOff(300);
  }
  if (FlashState == 2) {
  flasher2.setOnOff(300);
  }  
  
  // Get a reading from the buttons
  button5.update();   // Button 1
  button6.update();   // Button 2
  button7.update();   // Button 3
  button8.update();   // Button 4   
  
  if (button5.fallingEdge()) {   // BUTTON 1
  FlashState = 1;  // Set Flash index to correct Flasher routine (Flasher1, Flasher2 etc.)
  } 
  
  if (button6.fallingEdge()) {   // BUTTON 2
   // Turn off flasher(s) and extinguish LEDs
   FlashState = 0;
   flasher1.setOnOff(PIN_OFF);  // STOP Flasher  
   digitalWrite(14, LOW);       // Turn Off all LEDs
   digitalWrite(16, LOW);       //  
  }
  
  if (button7.fallingEdge()) {   // BUTTON 3
   FlashState = 2;  // Set Flash index to correct Flasher routine
  }
   
  if (button8.fallingEdge()) {   // BUTTON 4
   // Turn off flasher(s) and extinguish LEDs
   FlashState = 0;
   flasher2.setOnOff(PIN_OFF);  // STOP Flasher 
   digitalWrite(14, LOW);       // Turn Off all LEDs
   digitalWrite(16, LOW);       //
  }
}  // Loop Exit Point

I hope this is useful. If anyone notices any errors in the text it would be best to correct or explain the error.

Thanks.
 
Back
Top