Fading LEDs without a for() loop and delays.. This seems like it should be simple

Fading LEDs without a for() loop and delays… This seems like it should be simple but I’m having trouble.

Question 1: I want to have all 120 of my LEDs on at full brightness and have them slowly fade to darkness without repeating (popping back on at full brightness when they reach 0), and without making a mode switch impossible while waiting for the for() loop to finish. Is there a function for this? Here’s how I’m doing it now:

for (int i=225; i>0; i–) {
BRIGHTNESS=i;
fill_solid(leds, NUM_LEDS, CHSV(HUE, SATURATION, BRIGHTNESS));
FastLED.show();
delay(20);
}

Question 2: Once I can accomplish that, I want to fade all but 3 of the LEDs to 0, and leave those 3 (non-sequential) LEDs at full brightness. This is another confusing “array problem” I think. I want to keep LEDs number 8, 9, and 19 on while fading the other 117 of them to black.

Can anyone point me in the right direction?

I see a keyword called “fadeToBlackBy” but I can’t figure out how to use it. :confused:

You are right about arrays being the answer to your full-bright LED issue.

Can’t help you with the fade to black, but I’ll have a look tomorrow, unless you get a prior answer.

I think it’s so cool to see people learning to program for the sake of glowing goodness.

Maybe I’ll write up some tutorials to introduce coding concepts using FastLED

#include <FastLED.h>

#define LED_PIN 6
#define NUM_LEDS 60*4
#define BRIGHTNESS 255
#define LED_TYPE WS2812B
#define COLOR_ORDER RGB
CRGB leds[NUM_LEDS];

void setup() {
FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS);
}

void loop() {
fadeToBlackBy( leds, NUM_LEDS, 5);
// above is the same as
// for(int i=0; i< NUM_LEDS;i++) led[i].fadeToBlackBy(5);
int i = random16(NUM_LEDS*24);
if ( i < NUM_LEDS ) {
leds[i] = CRGB::Blue;
}
FastLED.show();
}

Every time you call fadeToBlackBy it dims the pixels in question a little. Try this:

fadeToBlackBy( leds, NUM_LEDS, 10);

…and call it repeatedly until the whole led array is black.

Thanks, @Eric_Warnke .

One of my favorite “one liners” (ok, four) is this:

void loop() {
fadeToBlackBy( leds, NUM_LEDS, 10);
leds[ random16( NUM_LEDS ) ] += CHSV( random8(), 200, 255);
FastLED.show();
FastLED.delay(10);
}

“Confetti”! Soon to be seen in the new FastLED ‘demo’ example that I’m working up to show how to use different techniques…

If you need it to be decoupled from any other processing here is an idea. This is just pseduo-code off the top of my head, I double it will compile. This can be inserted into your busyloop and should run when needed without blocking.

unsigned long menu_fade_last = 0;
uint8_t doFade = 0;
uint8_t doneFade = 0;
uint8_t test_pixel = 100; //black test pixel

void menu_fade() {
// doFade is set externally to signal fade
// doneFade is set when test_pixel is black
if ( doFade && !doneFade && (((millis()-menu_fade_last)>20*1000))) {
if ( leds[test_pixel] == CRGB::Black ) {
doneFade = 1;
return;
}
menu_fade_last = millis();
for( int i = 0; i < NUM_LEDS; i++ ) {
//standard loop over all pixels
switch (i) {
case 1:
case 9:
case 17: // and any other exceptions
break;
default:
leds[i].fadeToBlackBy(1);
}
}
FastLED.show(); // should probably show if updated too.
}
}

@Eric_Warnke : I think you meant == in the pixel test.
Also FWIW, you can test if(pixel) for nonblack or if(!pixel) for black.

= vs == is my nemesis. So many hours lost to one character errors.

@Christopher_Smolinsk that would be AMAZING. This is such a struggle sometimes.

And I’m sorry… I still don’t quite get what to do here.

fadeToBlackBy( , , and <how much I want to fade by? Or what’s that last number mean?>)

I like the random twinkle confetti fading effect from @Eric_Warnke but how do I get every LED to slow fade from 255 to 0 at once? I’m trying to call fadeToBlackBy() over and over but it just blinks at me… :confused:

void Solid_fade(){
for(int i = 0; i < NUM_LEDS; i++) {
fadeToBlackBy( leds, NUM_LEDS, 5);}
FastLED.show();

}

What am I doing wrong?

fadetoblack is just a wrapper around scale8, the fade amount is the rescaling amount. So fade by “5” crunches your existing channels from 0-255 to 0-250 ( 255-5 ). So 255 becomes 250 and 50 becomes 49. Repeat this enough and they end up at black.

The reason the sample isn’t working is you are using the strip wide command in a loop designed for each led.

loop over number of steps do
fadeToBlackBy(leds. NUM_LEDS,6)
FastLED.show()

or

loop over number of steps
loop over pixels
leds[i].fadeToBlackBy(5)
FastLED.show()

The function should still work, so if it’s just blinking at you you might want to make sure the wiring is right and you are using the proper setup.

Support 101, at this point if you still can’t figure it out, please post ALL code so that we can see if there are other actions at play.

If its wired right I’m guessing the blinking is because you are still setting the strip to solid white somewhere else in the loop. So you set it to white, the loop you posted would make it go black in short order, and then the loop comes back around and you set the strip white again.

Took me all day but I did it! Thanks for all your help. Hopefully someday this simple stuff will just make sense to me…

void Fade_but_3() {
BRIGHTNESS–;
if (BRIGHTNESS < 0) {BRIGHTNESS = 255;}
for(int idex = 0 ; idex < NUM_LEDS; idex++ ) {
leds[idex] = CHSV(HUE, SATURATION, BRIGHTNESS);
leds[9] = CHSV(HUE, SATURATION, 255);
leds[8] = CHSV(HUE, SATURATION, 255);
leds[19] = CHSV(HUE, SATURATION, 255);
}
LEDS.show();
delay(20);
if (BRIGHTNESS == 0) {BRIGHTNESS = 255; ledMode++;}
}