FastLED function to fade/pulse LED brightness

I’ve referenced code on posts here, using FastLED to fade LEDs up and down, and I’ve got very unusual things happening, spent many hours trying to achieve this. Hoping someone can help?

What I’m trying to achieve is a constant pulse of LED’s fading from full to half brightness, then to full brightness again, constantly looping. In using the below, the == operand doesn’t work, I have to use < and >. This makes it work, but when ramps to full brightness, the strip flashes briefly before the fade starts.

brightness = brightness + fadeAmount;
if (brightness == 0 || brightness == 255) {
fadeAmount = -fadeAmount;
}

I’ve also tried, but not got working:
FastLED.setBrightness(gamma8[brightness]);
FastLED.show();

Can anyone point me in the right direction, especially with the half level requirement?

If your FadeAmount is not a whole number, you will not always fall into your limit check.

Try :
if (brightness <= 0 || brightness => 255) {
fadeAmount = -fadeAmount;
}

You should really do separate checks though.- if your FadeAmount manages to get your brightness > 255 - you could get stuck in an infinite loop. This would be more reliable :

if (brightness <= 0)
{
fadeAmount =- fadeAmount;
brightness = 0 + fadeAmount;
}
if (brightness >=255)
{
fadeAmount =- fadeAmount;
brightness = 255 + fadeAmount;
}

1 Like

Thanks Jammy! That stopped the LED flash I was having at 100% brightness, and changing your second if statement to a value of 155 instead of 255 got me exactly what I was after :slight_smile:

One further question I’m now struggling with; I want this effect to run 8 times every 15 minutes. When the effect is not running, the LEDs are to be set 100% brightness.

Here’s what I have, but it’s not working, if anyone can offer pointers? (note I am using millis as a contact debounce, as a button push triggers another LED effect - this shouldn’t be an issue though, right?)

const long interval = 10000; //interval at which to run Light_Pulse
void loop(){

unsigned long currentMillis = millis();

if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
Light_Pulse(); //activate Light_Pulse at interval time
}

Light_Max();                              //switch all LEDs on

}

void Light_Max(){
fill_solid(redLeds, NUM_LEDS, CRGB::Red);
FastLED.show();
}

void Light_Pulse(){
//fade count limits how many times Light_Pulse runs
for (int fade_count=0; fade_count <= 8; fade_count++){

    for(i=0; i< NUM_LEDS; i++){

    redLeds[i]    = CRGB::Red;                  //set colour
    redLeds[i].   fadeLightBy(brightness);  //apply the brightness
    }
    FastLED.show();
            
    brightness = brightness + fadeAmount; 
    
    if (brightness <= 0){                   
      fadeAmount = -fadeAmount;         
      brightness = 0 + fadeAmount;
    }
      if (brightness >= 155){              
      fadeAmount = -fadeAmount;
      brightness = 155 + fadeAmount;        
    }
    delay(30);                              
 }

}

What’s not working ?

Can you describe what the lights are currently doing ?

At power up, the LED comes on at 100% and stays that way (this is good). To test, I made the time to flash at 15 seconds instead of 15 minutes, and flash 2 times, instead of 8 So what I’m expecting to see is the light pulsing to occur twice every 15 seconds and go solid 100% in-between.
What’s happening is that every 15 seconds I get a very brief dimming to 50% (of about 0.5 second), before it returns to 100%…

void Light_Pulse(){

//fade count limits how many times Light_Pulse runs
for (int fade_count=0; fade_count <= 8; fade_count++){

for(i=0; i< NUM_LEDS; i++){

redLeds[i]    = CRGB::Red;                  //set colour
redLeds[i].   fadeLightBy(brightness);  //apply the brightness
}
FastLED.show();
        
brightness = brightness + fadeAmount; 

if (brightness <= 0){                   
  fadeAmount = -fadeAmount;         
  brightness = 0 + fadeAmount;
}
  if (brightness >= 155){              
  fadeAmount = -fadeAmount;
  brightness = 155 + fadeAmount;        
}
delay(30);                              

}
}

Your Light_Pulse function is wrong. It’s looping though 8 times, which is giving you 8 changes of brightness with a delay of 30 between each. You need another loop :

void Light_Pulse(){
//fade count limits how many times Light_Pulse runs
for (int fade_count=0; fade_count <= 8; fade_count++){
for (int fade_loop = 0; fade_loop < 135 * 2; fade_loop++) // 135 * 2 gives it the opportunity to go through 0 to 135 twice - assuming your fadeAmount is 1
brightness = 135; //Set this so its starts at full brightness
fadeAmount = -1; //Start from light to dark
{
for(i=0; i< NUM_LEDS; i++){

    redLeds[i]    = CRGB::Red;                  //set colour
    redLeds[i].   fadeLightBy(brightness);  //apply the brightness
    }
    FastLED.show();
        
    brightness = brightness + fadeAmount; 

    if (brightness <= 0){                   
      fadeAmount = -fadeAmount;         
      brightness = 0 + fadeAmount;
    }
      if (brightness >= 155){              
      fadeAmount = -fadeAmount;
      brightness = 155 + fadeAmount;        
    }
    delay(30);
}                              

}

1 Like

Wow, thanks, the extra loop should do the trick, I totally missed that logic…I’ve entered the modifications…strangely its got the same behaviour, except the dimming is now a super quick flash, every 15 seconds.

I’ve tried a few things with timings, going to 25 seconds instead of 15, and adjusting the fade_loop value to x4 instead of x2, but no change in outcome. I’m not understanding the hard-coding of a value for fadeAmount, but I’ll try and wrap my head around the logic to unravel this puzzle…

Is your delay(30) inside the new loop ?

Yes, it’s inside the new loop. I’ve triple checked the code and tried moving the delay, but no joy…yet…

I’ll take a look if you like - can you attach your code as a file ?

OK, thank you very much, I’ve zipped and attached.

(Attachment SmartLED_v8.zip is missing)

Hi - zip file was rejected, so I’ll paste the code below. I greatly appreciate your help!

// Program for Smart LED tape. Button debounce (working) and responds to a contact closure on pin8
// At power on, LEDS all on, colour solid. 4 pins output different colours
// so one this one program can be used for any roundel.
// Upon contact closure (5V n/o) momentary event, the following happens to all 4 colour pins:
// LEDS all off / all on fast pulse (x2), with a LED chase effect to finish
// Lights all on when this finishes, so roundel colour remains visible.
//
// 20/08/2020 tested stable, with 110k-Ohm resistor between GND and pin8
// 24/08/2020 tested stable, with 4 extenstions of Cat5 (185M) between 12V PSU & 5V relay and Arduino & LED strip
// 25/08/2020 V3_2: test code removed, leaving only code in use
// 30/09/2020 V5: code replacement with ALL leds on and off now (instead of quick increment)
// Timings adjusted for best responsiveness of flashes
// 02/10/2020 V8: Light_Pulse slowly fades between 50% - 100% brightness in a loop, to add minor animation to the solid ON state
// Added an interval timer, so a number of light pulses happen after an adjustable length of time of solid LEDs on
//
// by S.Arbuckle

#include <FastLED.h>

#define NUM_LEDS 38 //number of LEDs in the roundel strip
#define NUM_STRIPS 3
#define DATA_PIN_R 3
#define DATA_PIN_G 5
#define DATA_PIN_B 6
#define DATA_PIN_P 9
#define NUM_COLORS 3
#define LED_TYPE WS2812B
#define COLOR_ORDER RGB

//define input pins
const int PinIn = 8;
const long interval = 15000; //interval at which to run Light_Pulse
int i = 0;
int j = 0;
int brightness = 1;
int fadeAmount = 2;
int flashes = 1;
int buttonState1 = 0;
int lastButtonState = LOW; // the previous reading from the input pin

unsigned long lastDebounceTime = 0; //the last time the output pin was toggled
unsigned long debounceDelay = 200; //the debounce time; increase if the output flickers
unsigned long previousMillis = 0; //store the last time interval timer was updated

CRGB redLeds [NUM_LEDS];
CRGB greenLeds [NUM_LEDS];
CRGB blueLeds [NUM_LEDS];
CRGB purpleLeds[NUM_LEDS];

void setup() {
// tell FastLED about the LED strip configuration
FastLED.addLeds<LED_TYPE,DATA_PIN_R,COLOR_ORDER>(redLeds, NUM_LEDS);
FastLED.addLeds<LED_TYPE,DATA_PIN_G,COLOR_ORDER>(greenLeds, NUM_LEDS);
FastLED.addLeds<LED_TYPE,DATA_PIN_B,COLOR_ORDER>(blueLeds, NUM_LEDS);
FastLED.addLeds<LED_TYPE,DATA_PIN_P,COLOR_ORDER>(purpleLeds, NUM_LEDS);

pinMode(PinIn,INPUT);
digitalWrite(PinIn,LOW); // set initial trigger state
}

void loop(){
// read the state of the switch into a local variable:
int reading = digitalRead(PinIn);
unsigned long currentMillis = millis();

if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
Light_Pulse(); //activate Light_Pulse at interval time
}

Light_Max(); //switch all LEDs on

if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}

if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it’s been there for longer than the debounce
// delay, so take it as the actual current state:

if (reading != buttonState1) { // if the button state has changed:
buttonState1 = reading;

buttonState1 = digitalRead(PinIn); // only toggle if the new button state is HIGH
if (buttonState1 == HIGH) {
Flash_X();
}
}
}
// save the reading. Next time through the loop, it’ll be the lastButtonState:
lastButtonState = reading;
}

void Light_Max(){
fill_solid(redLeds, NUM_LEDS, CRGB::Red);
fill_solid(greenLeds, NUM_LEDS, CRGB::Green);
fill_solid(blueLeds, NUM_LEDS, CRGB::Blue);
fill_solid(purpleLeds, NUM_LEDS,CRGB::Purple);
FastLED.show();
}

void Light_Pulse(){
//fade count limits how many times Light_Pulse runs
for (int fade_count=0; fade_count <= 2; fade_count++){
for (int fade_loop = 0; fade_loop < 135 * 4; fade_loop++) // 135 * 2 gives it the opportunity to go through 0 to 135 twice
brightness = 135; //Set this so its starts at full brightness
fadeAmount = -1; //Start from light to dark
{
for(i=0; i< NUM_LEDS; i++){

redLeds[i] = CRGB::Red; //set colours in the array
greenLeds[i] = CRGB::Green;
blueLeds[i] = CRGB::Blue;
purpleLeds[i] = CRGB::Purple;

redLeds[i]. fadeLightBy(brightness); //apply the brightness
greenLeds[i]. fadeLightBy(brightness);
blueLeds[i]. fadeLightBy(brightness);
purpleLeds[i].fadeLightBy(brightness);
}
FastLED.show();

brightness = brightness + fadeAmount; //raise the brightness value

if (brightness <= 0){ //fade up
fadeAmount = -fadeAmount;
brightness = 0 + fadeAmount;
}
if (brightness >= 155){ //fade down (not to off)
fadeAmount = -fadeAmount;
brightness = 155 + fadeAmount; //0=full brightness, 255=minimum brightness
}
delay(10); //this setting is the speed of the brighness change
}
}
}

void Flash_X(){
for (j=0; j<=flashes; j++){

FastLED.clear(true); //all LED arrays cleared / off
delay(225); //delay time of transition for OFF to ON for flash sequence
fill_solid(redLeds, NUM_LEDS, CRGB::Red);
fill_solid(greenLeds, NUM_LEDS, CRGB::Green);
fill_solid(blueLeds, NUM_LEDS, CRGB::Blue);
fill_solid(purpleLeds, NUM_LEDS,CRGB::Purple);
FastLED.show(); //all LED arrays set to full brightness
delay(225); //delay time of transition for ON to OFF for flash sequence
}

for(i=0; i< NUM_LEDS; i++){
redLeds[i] = CRGB::Black;
greenLeds[i] = CRGB::Black;
blueLeds[i] = CRGB::Black;
purpleLeds[i] = CRGB::Black;
FastLED.show(); //all LED arrays set to increment off pixels
delay(8); //this setting is the speed of pixel movement
}
}

Try this :

/ Program for Smart LED tape. Button debounce (working) and responds to a contact closure on pin8

// At power on, LEDS all on, colour solid. 4 pins output different colours
// so one this one program can be used for any roundel.
// Upon contact closure (5V n/o) momentary event, the following happens to all 4 colour pins:
// LEDS all off / all on fast pulse (x2), with a LED chase effect to finish
// Lights all on when this finishes, so roundel colour remains visible.
//
// 20/08/2020 tested stable, with 110k-Ohm resistor between GND and pin8
// 24/08/2020 tested stable, with 4 extenstions of Cat5 (185M) between 12V PSU & 5V relay and Arduino & LED strip
// 25/08/2020 V3_2: test code removed, leaving only code in use
// 30/09/2020 V5: code replacement with ALL leds on and off now (instead of quick increment)
// Timings adjusted for best responsiveness of flashes
// 02/10/2020 V8: Light_Pulse slowly fades between 50% - 100% brightness in a loop, to add minor animation to the solid ON state
// Added an interval timer, so a number of light pulses happen after an adjustable length of time of solid LEDs on
//
// by S.Arbuckle

#include <FastLED.h>

#define NUM_LEDS 38 //number of LEDs in the roundel strip
#define NUM_STRIPS 3
#define DATA_PIN_R 3
#define DATA_PIN_G 5
#define DATA_PIN_B 6
#define DATA_PIN_P 9
#define NUM_COLORS 3
#define LED_TYPE WS2812B
#define COLOR_ORDER RGB

//define input pins
const int PinIn = 8;
const long interval = 15000; //interval at which to run Light_Pulse
int i = 0;
int j = 0;
int brightness = 1;
int fadeAmount = 2;
int flashes = 1;
int buttonState1 = 0;
int lastButtonState = LOW; // the previous reading from the input pin

unsigned long lastDebounceTime = 0; //the last time the output pin was toggled
unsigned long debounceDelay = 200; //the debounce time; increase if the output flickers
unsigned long previousMillis = 0; //store the last time interval timer was updated

CRGB redLeds [NUM_LEDS];
CRGB greenLeds [NUM_LEDS];
CRGB blueLeds [NUM_LEDS];
CRGB purpleLeds[NUM_LEDS];

void setup()
{
// tell FastLED about the LED strip configuration
FastLED.addLeds<LED_TYPE,DATA_PIN_R,COLOR_ORDER>(redLeds, NUM_LEDS);
FastLED.addLeds<LED_TYPE,DATA_PIN_G,COLOR_ORDER>(greenLeds, NUM_LEDS);
FastLED.addLeds<LED_TYPE,DATA_PIN_B,COLOR_ORDER>(blueLeds, NUM_LEDS);
FastLED.addLeds<LED_TYPE,DATA_PIN_P,COLOR_ORDER>(purpleLeds, NUM_LEDS);

pinMode(PinIn,INPUT);
digitalWrite(PinIn,LOW); // set initial trigger state

}

void loop()
{
// read the state of the switch into a local variable:
int reading = digitalRead(PinIn);
unsigned long currentMillis = millis();

if (currentMillis - previousMillis >= interval) 
{
	previousMillis = currentMillis;
	Light_Pulse(); //activate Light_Pulse at interval time
}

Light_Max(); //switch all LEDs on

if (reading != lastButtonState) 
{
	// reset the debouncing timer
	lastDebounceTime = millis();
}

if ((millis() - lastDebounceTime) > debounceDelay) 
{
	// whatever the reading is at, it’s been there for longer than the debounce
	// delay, so take it as the actual current state:
	if (reading != buttonState1) 
	{
		// if the button state has changed:
		buttonState1 = reading;
		buttonState1 = digitalRead(PinIn); // only toggle if the new button state is HIGH
		if (buttonState1 == HIGH) 
		{
			Flash_X();
		}
	}
}
// save the reading. Next time through the loop, it’ll be the lastButtonState:
lastButtonState = reading;

}

void Light_Max()
{
fill_solid(redLeds, NUM_LEDS, CRGB::Red);
fill_solid(greenLeds, NUM_LEDS, CRGB::Green);
fill_solid(blueLeds, NUM_LEDS, CRGB::Blue);
fill_solid(purpleLeds, NUM_LEDS,CRGB::Purple);
FastLED.show();
}

void Light_Pulse()
{
//fade count limits how many times Light_Pulse runs
for (int fade_count=0; fade_count <= 2; fade_count++)
{
brightness = 135; //Set this so its starts at full brightness
fadeAmount = -1; //Start from light to dark
for (int fade_loop = 0; fade_loop < 135 * 4; fade_loop++) // 135 * 2 gives it the opportunity to go through 0 to 135 twice
{
for(i=0; i< NUM_LEDS; i++)
{
redLeds[i] = CRGB::Red; //set colours in the array
greenLeds[i] = CRGB::Green;
blueLeds[i] = CRGB::Blue;
purpleLeds[i] = CRGB::Purple;

			redLeds[i]. fadeLightBy(brightness); //apply the brightness
			greenLeds[i]. fadeLightBy(brightness);
			blueLeds[i]. fadeLightBy(brightness);
			purpleLeds[i].fadeLightBy(brightness);
		}
		FastLED.show();

		brightness = brightness + fadeAmount; //raise the brightness value

		if (brightness <= 0)
		{ //fade up
			fadeAmount = -fadeAmount;
			brightness = 0 + fadeAmount;
		}
		if (brightness >= 155)
		{ //fade down (not to off)
			fadeAmount = -fadeAmount;
			brightness = 155 + fadeAmount; //0=full brightness, 255=minimum brightness
		}
		delay(10); //this setting is the speed of the brighness change
	}
}

}

void Flash_X()
{
for (j=0; j<=flashes; j++)
{
FastLED.clear(true); //all LED arrays cleared / off
delay(225); //delay time of transition for OFF to ON for flash sequence
fill_solid(redLeds, NUM_LEDS, CRGB::Red);
fill_solid(greenLeds, NUM_LEDS, CRGB::Green);
fill_solid(blueLeds, NUM_LEDS, CRGB::Blue);
fill_solid(purpleLeds, NUM_LEDS,CRGB::Purple);
FastLED.show(); //all LED arrays set to full brightness
delay(225); //delay time of transition for ON to OFF for flash sequence
}

for(i=0; i< NUM_LEDS; i++)
{
	redLeds[i] = CRGB::Black;
	greenLeds[i] = CRGB::Black;
	blueLeds[i] = CRGB::Black;
	purpleLeds[i] = CRGB::Black;
	FastLED.show(); //all LED arrays set to increment off pixels
	delay(8); //this setting is the speed of pixel movement
}

}

Hi - thanks for your help…it’s close but not quite there. On first run, LEDs come on for the preset time ok, pulsing of lights starts, but never stops.

It was just these two lines you moved above the loop, yes? I’ve looked carefully to see if there are any other changes, but have I missed any?

brightness = 135; //Set this so its starts at full brightness
fadeAmount = -1; //Start from light to dark

Thank you, Sean.

Hmm … I’ve looked through the code, and it appears to be ok.

Try increasing the const long interval = 15000 - it maybe taking so long to run the flash routine, it starts again immediately ?

Yes, increasing the interval does the trick! Brilliant, thanks! I’ve a side effect off the button read being disabled while the pulse loop runs, I don’t think there’s a workaround for that, is there?

Yes - you could put a test in the loop for the button, if it’s pressed, you call a “break;” - that will cancel the loop.

I would set up a bool at the start of the function, and “break” if true on all of the loops.

Hi again - could I bend your ear one more time? I’ve put a boolean in, and breaks in the loops, but it’s not functioning (button press trigger a lights flash during light fade effect).

// Program for Smart LED tape. Button debounce (working) and responds to a contact closure on pin8
// At power on, LEDS all on, colour solid. 4 pins output different colours
// so one this one program can be used for any roundel.
// Upon contact closure (5V n/o) momentary event, the following happens to all 4 colour pins:
// LEDS all off / all on fast pulse (x2), with a LED chase effect to finish
// Lights all on when this finishes, so roundel colour remains visible.
//
// 20/08/2020 tested stable, with 110k-Ohm resistor between GND and pin8
// 24/08/2020 tested stable, with 4 extenstions of Cat5 (185M) between 12V PSU & 5V relay and Arduino & LED strip
// 25/08/2020 V3_2: test code removed, leaving only code in use
// 30/09/2020 V5: code replacement with ALL leds on and off now (instead of quick increment)
// Timings adjusted for best responsiveness of flashes
// 02/10/2020 V8: Light_Pulse slowly fades between 50% - 100% brightness in a loop, to add minor animation to the solid ON state
// Added an interval timer, so a number of light pulses happen after an adjustable length of time of solid LEDs on
// 05/10/2020 V9: added a check for if a tag event happens while Light_Pulse is in progress, break out and execute Flash_X
//
// by S.Arbuckle

#include <FastLED.h>

#define NUM_LEDS 38 //number of LEDs in the roundel strip
#define NUM_STRIPS 3
#define DATA_PIN_R 3
#define DATA_PIN_G 5
#define DATA_PIN_B 6
#define DATA_PIN_P 9
#define NUM_COLORS 3
#define LED_TYPE WS2812B
#define COLOR_ORDER RGB

//define input pins
const int PinIn = 8;
const long interval = 18000; //interval at which to run Light_Pulse
int i = 0;
int j = 0;
int brightness = 1;
int fadeAmount = 2;
int flashes = 1;
int buttonState1 = 0;
int lastButtonState = LOW; //the previous reading from the input pin
bool ButtonBreak = LOW; //variable to monitor for tag event, while Light_Pulse is in progress

unsigned long lastDebounceTime = 0; //the last time the output pin was toggled
unsigned long debounceDelay = 200; //the debounce time; increase if the output flickers
unsigned long previousMillis = 0; //store the last time interval timer was updated

CRGB redLeds [NUM_LEDS];
CRGB greenLeds [NUM_LEDS];
CRGB blueLeds [NUM_LEDS];
CRGB purpleLeds[NUM_LEDS];

void setup() {
// tell FastLED about the LED strip configuration
FastLED.addLeds<LED_TYPE,DATA_PIN_R,COLOR_ORDER>(redLeds, NUM_LEDS);
FastLED.addLeds<LED_TYPE,DATA_PIN_G,COLOR_ORDER>(greenLeds, NUM_LEDS);
FastLED.addLeds<LED_TYPE,DATA_PIN_B,COLOR_ORDER>(blueLeds, NUM_LEDS);
FastLED.addLeds<LED_TYPE,DATA_PIN_P,COLOR_ORDER>(purpleLeds, NUM_LEDS);

pinMode(PinIn,INPUT);
digitalWrite(PinIn,LOW); // set initial trigger state
}

void loop(){
// read the state of the switch into a local variable:
int reading = digitalRead(PinIn);
unsigned long currentMillis = millis();

if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
Light_Pulse(); //activate Light_Pulse at interval time
}

Light_Max(); //switch all LEDs on

if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}

if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it’s been there for longer than the debounce
// delay, so take it as the actual current state:

if (reading != buttonState1) { // if the button state has changed:
buttonState1 = reading;

buttonState1 = digitalRead(PinIn); // only toggle if the new button state is HIGH
if (buttonState1 == HIGH) {
ButtonBreak = HIGH; //to interrupt Light_Pulse if the button state changes
Flash_X();
}
}
}
// save the reading. Next time through the loop, it’ll be the lastButtonState:
lastButtonState = reading;
}

void Light_Max(){
fill_solid(redLeds, NUM_LEDS, CRGB::Red);
fill_solid(greenLeds, NUM_LEDS, CRGB::Green);
fill_solid(blueLeds, NUM_LEDS, CRGB::Blue);
fill_solid(purpleLeds, NUM_LEDS,CRGB::Purple);
FastLED.show();
}

void Light_Pulse(){
//fade count limits how many times Light_Pulse runs
for (int fade_count=0; fade_count <= 5; fade_count++)
{
// brightness = 1; //Set this so its starts at full brightness
if (ButtonBreak == HIGH){ //to interrupt Light_Pulse if the button state changes
Flash_X();
break;
}
fadeAmount = -1; //Start from light to dark

for (int fade_loop = 0; fade_loop < 150; fade_loop++){ // 135 * 2 gives it the opportunity to go through 0 to 135 twice

for(i=0; i< NUM_LEDS; i++){

if (ButtonBreak == HIGH){ //to interrupt Light_Pulse if the button state changes
Flash_X();
break;
}
redLeds[i] = CRGB::Red; //set colours in the array
greenLeds[i] = CRGB::Green;
blueLeds[i] = CRGB::Blue;
purpleLeds[i] = CRGB::Purple;

redLeds[i]. fadeLightBy(brightness); //apply the brightness
greenLeds[i]. fadeLightBy(brightness);
blueLeds[i]. fadeLightBy(brightness);
purpleLeds[i].fadeLightBy(brightness);
}
FastLED.show();

brightness = brightness + fadeAmount; //raise the brightness value

if (brightness <= 0){ //fade up
fadeAmount = -fadeAmount;
brightness = 0 + fadeAmount;
}
if (brightness >= 155){ //fade down (not to off)
fadeAmount = -fadeAmount;
brightness = 255 + fadeAmount; //0=full brightness, 255=minimum brightness
}
delay(10); //this setting is the speed of the brighness change
}
}
}

void Flash_X(){
for (j=0; j<=flashes; j++){

FastLED.clear(true); //all LED arrays cleared / off
delay(225); //delay time of transition for OFF to ON for flash sequence
fill_solid(redLeds, NUM_LEDS, CRGB::Red);
fill_solid(greenLeds, NUM_LEDS, CRGB::Green);
fill_solid(blueLeds, NUM_LEDS, CRGB::Blue);
fill_solid(purpleLeds, NUM_LEDS,CRGB::Purple);
FastLED.show(); //all LED arrays set to full brightness
delay(225); //delay time of transition for ON to OFF for flash sequence
}

for(i=0; i< NUM_LEDS; i++){
redLeds[i] = CRGB::Black;
greenLeds[i] = CRGB::Black;
blueLeds[i] = CRGB::Black;
purpleLeds[i] = CRGB::Black;
FastLED.show(); //all LED arrays set to increment off pixels
delay(8); //this setting is the speed of pixel movement
}
ButtonBreak = LOW;
}

I used the previous code I sent, because I had formatted it with the correct indentations etc - I haven’t looked through what you sent, because I’d have to format it again.

Basically, I created a function Button_Check - this returns true or false. This function is then called in your Light_Pulse function, and if true, will break out of the loops and call your Flash_X before it exits.

// Program for Smart LED tape. Button debounce (working) and responds to a contact closure on pin8
// At power on, LEDS all on, colour solid. 4 pins output different colours
// so one this one program can be used for any roundel.
// Upon contact closure (5V n/o) momentary event, the following happens to all 4 colour pins:
// LEDS all off / all on fast pulse (x2), with a LED chase effect to finish
// Lights all on when this finishes, so roundel colour remains visible.
//
// 20/08/2020 tested stable, with 110k-Ohm resistor between GND and pin8
// 24/08/2020 tested stable, with 4 extenstions of Cat5 (185M) between 12V PSU & 5V relay and Arduino & LED strip
// 25/08/2020 V3_2: test code removed, leaving only code in use
// 30/09/2020 V5: code replacement with ALL leds on and off now (instead of quick increment)
// Timings adjusted for best responsiveness of flashes
// 02/10/2020 V8: Light_Pulse slowly fades between 50% - 100% brightness in a loop, to add minor animation to the solid ON state
// Added an interval timer, so a number of light pulses happen after an adjustable length of time of solid LEDs on
//
// by S.Arbuckle

#include <FastLED.h>

#define NUM_LEDS 38 //number of LEDs in the roundel strip
#define NUM_STRIPS 3
#define DATA_PIN_R 3
#define DATA_PIN_G 5
#define DATA_PIN_B 6
#define DATA_PIN_P 9
#define NUM_COLORS 3
#define LED_TYPE WS2812B
#define COLOR_ORDER RGB

//define input pins
const int PinIn = 8;
const long interval = 15000; //interval at which to run Light_Pulse
int i = 0;
int j = 0;
int brightness = 1;
int fadeAmount = 2;
int flashes = 1;
int buttonState1 = 0;
int lastButtonState = LOW; // the previous reading from the input pin

unsigned long lastDebounceTime = 0; //the last time the output pin was toggled
unsigned long debounceDelay = 200; //the debounce time; increase if the output flickers
unsigned long previousMillis = 0; //store the last time interval timer was updated

CRGB redLeds [NUM_LEDS];
CRGB greenLeds [NUM_LEDS];
CRGB blueLeds [NUM_LEDS];
CRGB purpleLeds[NUM_LEDS];

void setup()
{
// tell FastLED about the LED strip configuration
FastLED.addLeds<LED_TYPE,DATA_PIN_R,COLOR_ORDER>(redLeds, NUM_LEDS);
FastLED.addLeds<LED_TYPE,DATA_PIN_G,COLOR_ORDER>(greenLeds, NUM_LEDS);
FastLED.addLeds<LED_TYPE,DATA_PIN_B,COLOR_ORDER>(blueLeds, NUM_LEDS);
FastLED.addLeds<LED_TYPE,DATA_PIN_P,COLOR_ORDER>(purpleLeds, NUM_LEDS);

pinMode(PinIn,INPUT);
digitalWrite(PinIn,LOW); // set initial trigger state

}

void loop()
{
// read the state of the switch into a local variable:
int reading = digitalRead(PinIn);
unsigned long currentMillis = millis();

if (currentMillis - previousMillis >= interval) 
{
	previousMillis = currentMillis;
	Light_Pulse(); //activate Light_Pulse at interval time
}

Light_Max(); //switch all LEDs on

if (Check_Button == true)
{
	Flash_X();
}

}

bool Check_Button()
{
if (reading != lastButtonState)
{
// reset the debouncing timer
lastDebounceTime = millis();
}

if ((millis() - lastDebounceTime) > debounceDelay) 
{
	// whatever the reading is at, it’s been there for longer than the debounce
	// delay, so take it as the actual current state:
	if (reading != buttonState1) 
	{
		// if the button state has changed:
		buttonState1 = reading;
		buttonState1 = digitalRead(PinIn); // only toggle if the new button state is HIGH
		if (buttonState1 == HIGH) 
		{
			return true;
		}
	}
}
// save the reading. Next time through the loop, it’ll be the lastButtonState:
lastButtonState = reading;
return false;

}

void Light_Max()
{
fill_solid(redLeds, NUM_LEDS, CRGB::Red);
fill_solid(greenLeds, NUM_LEDS, CRGB::Green);
fill_solid(blueLeds, NUM_LEDS, CRGB::Blue);
fill_solid(purpleLeds, NUM_LEDS,CRGB::Purple);
FastLED.show();
}

void Light_Pulse()
{
bool ButtonPressed = false;
//fade count limits how many times Light_Pulse runs
for (int fade_count=0; fade_count <= 2; fade_count++)
{
brightness = 135; //Set this so its starts at full brightness
fadeAmount = -1; //Start from light to dark
for (int fade_loop = 0; fade_loop < 135 * 4; fade_loop++) // 135 * 2 gives it the opportunity to go through 0 to 135 twice
{
ButtonPressed = Check_Button();
if (ButtonPressed)
{
break; //If the button is pressed, we will exit out of this fade_loop
}

		for(i=0; i< NUM_LEDS; i++)
		{
			redLeds[i] = CRGB::Red; //set colours in the array
			greenLeds[i] = CRGB::Green;
			blueLeds[i] = CRGB::Blue;
			purpleLeds[i] = CRGB::Purple;

			redLeds[i]. fadeLightBy(brightness); //apply the brightness
			greenLeds[i]. fadeLightBy(brightness);
			blueLeds[i]. fadeLightBy(brightness);
			purpleLeds[i].fadeLightBy(brightness);
		}
		FastLED.show();

		brightness = brightness + fadeAmount; //raise the brightness value

		if (brightness <= 0)
		{ //fade up
			fadeAmount = -fadeAmount;
			brightness = 0 + fadeAmount;
		}
		if (brightness >= 155)
		{ //fade down (not to off)
			fadeAmount = -fadeAmount;
			brightness = 155 + fadeAmount; //0=full brightness, 255=minimum brightness
		}
		delay(10); //this setting is the speed of the brighness change
	}
	if (ButtonPressed)
	{
		break;	//If the button was pressed, we exit out of the fade_count loop too
	}
}
if (ButtonPressed)
{
	Flash_X();
}

}

void Flash_X()
{
for (j=0; j<=flashes; j++)
{
FastLED.clear(true); //all LED arrays cleared / off
delay(225); //delay time of transition for OFF to ON for flash sequence
fill_solid(redLeds, NUM_LEDS, CRGB::Red);
fill_solid(greenLeds, NUM_LEDS, CRGB::Green);
fill_solid(blueLeds, NUM_LEDS, CRGB::Blue);
fill_solid(purpleLeds, NUM_LEDS,CRGB::Purple);
FastLED.show(); //all LED arrays set to full brightness
delay(225); //delay time of transition for ON to OFF for flash sequence
}

for(i=0; i< NUM_LEDS; i++)
{
	redLeds[i] = CRGB::Black;
	greenLeds[i] = CRGB::Black;
	blueLeds[i] = CRGB::Black;
	purpleLeds[i] = CRGB::Black;
	FastLED.show(); //all LED arrays set to increment off pixels
	delay(8); //this setting is the speed of pixel movement
}

}

Should work, but I don’t have the hardware you have - I’m programming in Notepad++

If you paste your code this way it will format right:

```C++
<your code goes here>
```

You can edit old posts to fix that up, too. :slight_smile:

2 Likes