I'm trying to learn/teach through some FastLED tutorials,

I’m trying to learn/teach through some FastLED tutorials, and was playing around with various ways to make a pixel go back and forth or cycle a strip with a fading tail behind it. I was going to give fadeLightBy() or fadeToBlackBy() a try, but get really weird results! Here’s the code:
--------
void loop()
{

leds[lead_dot].b = 255;
lead_dot = lead_dot + 1;

for(int dot = 0; dot < NUM_LEDS; dot++)
{

leds[dot].fadeToBlackBy(64);  

}

FastLED.show();

delay(20);
}
--------

It runs a couple of blue pulses and then just freezes for a bit before turning the pixels a bunch of yellow/red tones (attached pic, though as you can figure it’s hard to capture). Then it literally acts “laggy” when it resumes and the lead pixel/tail stop toward the end of the strip indefinitely.

If I simply replace the fadeToBlackBy() line with this, it’s fine:

leds[dot] /= 2;

Why can I divide all channels by 2, but not use fadeToBlackBy()?

I hate counting up and counting down a strip in order to move pixels. I also hate that about as much as using delays (especially when I’ve got button polling routines to run). Without going into all the code, I’d recommend that you try:

beatsin8() to move your active pixel back and forth and to use EVERY_N_MILLISECONDS() to call the fadetoblackby() function every few milliseconds.

Example:

uint8_t curpixel = beatsin8(BeatsPerMinute,0,NUM_LEDS);
led[curpixel] = CHSV(20,255,255);

EVERY_N_MILLISECONDS(20) {
fadeToBlackBy(leds, NUM_LEDS, fadeval);
}
FastLED.show();

or something along those lines. Anyways, by using those, you can do without the blocking delay and without counting up and down the string of pixels.

Hope that helps.

I hate both of those as well, but haven’t dug into every_n_milliseconds and hadn’t even heard of beatsin8. Thanks for the pointers.

Hmmm. Your use of fadeToBlackBy had me look up the docs. I was following the github wiki which just seems to pass the function a fractional amount to fade by. Your code (and the 3.1 docs now that I checked) pass it the array, num_leds, and a fade value. Maybe the issue was mixing old function syntax with v3.1?

You can fadetoblackby a single LED or the whole array. Oh, and I currently keep all my tips, tricks & traps at:

https://github.com/atuline/FastLED-Demos/blob/master/fastled_tips_snippets.ino

Thanks @Andrew_Tuline ! So, couple of revelations… while I’m ~99% sure I had it at one point, I don’t have a line like if(lead_dot > NUM_LEDS - 1) { lead_dot = 0; }! I think that’s what was glitching things. Not sure about the internals of FastLED, so I’m not sure what happens when it sends data including values for a pixel that doesn’t exist in hardware. Using that line fixed the issue.

I also confirmed that both variants of fadeToBlackBy work (the one inside the for loop above, as well as removing the for loop entirely and just using fadeToBlackBy(leds, NUM_LEDS, amount) each loop.

Lastly, thanks so much for the intro to beatsin8. That works just swell, as does the EVERY_N_MILLISECONDS line. Is EVERY_N_MILLISECONDS just a wrapper for a millis() based timing check? Like:

if(millis() - prev_millis > delay) { … }

I tried to find the function in the 3.1 docs but am coming up empty handed. I found an announcement for the feature here (https://plus.google.com/112916219338292742137/posts/HyNmBHfWm27), but nothing else.

Try: https://github.com/FastLED/FastLED/blob/master/lib8tion.h

Yeah, I’m not really able to digest that, but I’m going to take it as “Yes, this is implementing a millis()-based timer” vs. a delay. I definitely get the advantage and have run into this using encoders, so I’m glad it’s there. For simple stuff I often just use delay().

Just finished the post this was for, and referenced your awesome tips, @Andrew_Tuline !

Awesome article. Hope you gets lots of readers.