super basic one this one...

super basic one this one…

this example fades in a single led, then proceeds to the next led and then fades that one in…

for (int i = NUMLEDS; i < 0; i–) {
for (int fade = 0; fade < 255; fade++)) {
colourPicker();
leds[i] = CHSV( huev, sat, fade);
FastLED.show();
}
}

unfortunately, this will lock out the arduino whilst the fade is happening… I’ve tried wrapping my head around the EVERY_N_MILLISECONDS, and i can fade the entire strip, but how can i fade 20 leds, like this?

how can i make this more fluid?

your have a nestled pair of “for loops”. This is efficient as long as you do not want to do anything else. to do other things, open up one of both of them to run in the main loop.

for example, open one

you could get rid of the outer for loop and just have the inner one run within your main code loop. you will need to add a counter for i that increments on each time through the main loop and resets if I is bigger than NUMLEDs. this way you can have other code run in between fading each led.

or open both…

or expand on that, also get rid of the 2nd for loop and run the balance of that code in your main loop, now increment fade every time through the loop and then reset fade to 0 and increment i every time that fade reaches 255 (also resetting i when it is bigger than NUMLEDS).

You are referring to leds[NUMLEDS], which will break your program . . . sometimes. The last LED in the strip should be leds[NUMLEDS-1]. Am also wondering about the i < 0. I would think if you’re counting down, that the outerloop would be:

for (int i = NUMLEDS-1; i >= 0; i–) {

Like Mark, I’m not too keen on nested loops though.

Adding a delay will allow other tasks to run, of you’re using an ESP chip. You can also use the FastLED delay.

@Sam_Guyer Can you give a bit more info? How does using delay or FastLED.delay still allow other stuff to run?

@marmil Indeed. I would love to see an example of that.

@Andrew_Tuline , @marmil ‘delay’ (really the ‘yield’ statement in the delay functoin) is architecture dependent. If you don’t have an ESP chip, then it almost certainly won’t work. For example, there is no implementation of ‘yield’ in the Arduino standard library, even though the function exists. It’s empty and it doesn’t do anything. In hooks.c it’s there to be implemented by future devs. FastLED itself does not define a working yield function either.

For any chip that doesn’t have it, something like the below could substitute:

CHUNKS=10;
PREV_LED=0;
LED_PER_CHUNK=20; // or NUM_LEDS/CHUNKS

def foo_all_leds() {
for(int led=PREV_LED+1; led <(PREV_CHUNK + LED_PER_CHUNK); led++) {
// set leds to do stuff
}
PREV_LED=led;
}

loop() {
if (CHUNKS > 0) {
foo_all_leds();
CHUNKS–;
} else {
FastLED.show();
}
// Do other stuff here like check input puts or whatever
}

This isn’t great, it’s just to illustrate the flow. Depending how much you need to do, you change the chunk size. You can reset CHUNKS and PREV_LED as you need to do other LED stuff, turn them off or whatever.

The point is to keep the main loop free of everything except managing which task is executing and when. CHUCKS determines when the leds might get set, PREV_LED determines if any more leds need to be set. Let the ‘loop’ function be as fast as possible to hand off control between different tasks.

Hopefully this helps.

opening the loop breaks either the loop, or the effect.

the desired outcome, is;
when triggered, led1 fades in
after a time, led2 fades in
after a time, led3 fades in.

in the current code, led1 must get to 255, before continuing to led2. what i would like to achieve is led2 starting before led1 has finished, or to wait for a second before led starts.

@Kelvin_Mead Including the main loop, you are using 3 loops to do what can be done with 1. You are locking out the Arduino while ALL the fading is happening.
Also note that FastLED.show() does not have to be called immediately.

Here is it in just the main loop.
// example

brightness = 0;
b_up = true;
l_up = true;
led = 0;

loop() {
LEDS[led] = brightness;
LEDS[led+1] = brightness-1;
/// etc
FastLED.show();

// direction
if(b_up) {
brightness++;
} else {
brightness-; //
}

//flip from going up to going down
if(brightness == 255 || brightness == 0) {
b_up =~b_up;
}

// increment led
if(brightess == 0 && up == false) {
if (l_up) {
led++;
} else {
led-;
}
}

// flip led direction
if (led == num_led - 1 || led == 0) {
l_up = ~l_up;
}

// END

You can do whatever you want here. You can add any other code into the main loop. if your main loop is fast enough, you’ll have the other work in between the blinking. This is non-blocking. If you have other long functions which are blocking, you need to refactor those as well. I’ll leave completing the boundary conditions to you, you’ll want to flip the LED’s depending if you want a chase or a reflection off the ends.

I’m not sure what you mean by smooth, you might want to look at FastLED’s math functions.

Here’s an undebugged .ino that fades in LED’s over time one at a time in an increasing order:

Uses a single loop, a bit of early high school arithmetic and currently no delay statements. Doesn’t quite do what I want, but it’s close enough.

Just to note you are really using 2 loops, the ‘for’ loop and the ‘loop’ loop. The more you think of the ‘loop()’ function as nothing special other than a “while” loop, you will be able to use it very effectively to your advantage.

Try the following.

Method 1:
Visualize a box around the LEDs you want to overlap. Those can all be addressed as a “window” around the led counter. e.g., if you are on i = 10 on this loop, then update LEDs 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 (10-5, 10-4, 10-3, 10-2, 10-1, 10, 10+1, 10+2, 10+3, 10+4)

e.g.
leds[i-5]=CHVS(255,0,temp-5);
leds[i-4]=CHVS(255,0,temp-4);
leds[i-3]=CHVS(255,0,temp-3);

leds[i+4]=CHVS(255,0,temp+4);

You would need to change “temp+x” to get the effect you want, and again handle boundaries.

Method 2:
Consider triwave8:
“input output 0…127 0…254 (positive slope) 128…255 254…0 (negative slope)”
That sentence is awful, but it is saying that as the input goes from 0-127, the function increases, and from 128-255, the function decreases back to 0. So the brightness will go up and down from 0-255.

led[i] = CHVS(255,0, triwave8(i+x));

x is an integer which always increases at each step, x++. It can overflow as it will go back to 0, and the triwave8 function will handle it properly: triwave8(0) = triwave8(255)

multiplying (i+x) by something will increase the number of waves in the line:
led[i] = CHVS(255,0,triwave8(10*(i+x))

docs and examples:

http://fastled.io/docs/3.1/group__lib8tion.html#gae9e011ff745ade1164ae77b0ef62bfac