Hey Daniel Garcia os Mark Kriegsman , with my POV sticks,

Hey @Daniel_Garcia os @Mark_Kriegsman , with my POV sticks, I read in RGB data into the leds array and display that. What I’d like to do is perform a fade-to-black from there. I don’t want to use setBrightness because I lose color fidelity, so I thought maybe I can use the Value in the HSV color space. But then … how the heck do I do that. I have 48 pixels and each will need to be adjusted accordingly. That’s a simple loop, but how do I take what was set as RGB values in the leds array and manipulate it as if it was HSV?

loop thru leds[x] = CRGB(CHSV(leds[x]).value-= FadeBy) maybe? something along those lines in psuedocode?

Will that even work? Ah crap, I’ll write a test script really quick …

// Dim a color by 25% (64/256ths)
// eventually fading to full black
leds[i].fadeToBlackBy( 64 );

Will this work?

No, we don’t have a conversion from HSV to RGB. But what you could do is continual scaling down, e.g. leds[x].nscale8(250); (dim each color by 2% (aka 250/255) - you could also used leds[x] %= 250; however that uses nscale8_video under the hood, which means it tries to not scale down to black.

Ok, nscale8() to the rescue. Works for what I want it to do. Now for a more, uh, complicated scenario. I have the following code:

void HSVRainbow() {
static uint8_t hue = 0;
if (millis() - patternLastRun > 10) {
if (!off) {
leds[0] = CHSV(hue, 255, 255);
} else {
leds[0] = CHSV(0, 0, 0);
}
cntr++;
if (cntr > 5) {
cntr = 0;
off = !off;
hue += 15;
}
LEDS.show();
for (int px = NUM_LEDS - 1; px > 0; px–) {
leds[px] = leds[px - 1];
}
patternLastRun = millis();
}
}

That creates a pattern of 6 pixels on and 6 pixels off while pushing it along the full string. So when the full string is lit, you get an alternating on/off effect for every 6 pixels in a chase. On top of that, each lit section is a color of the rainbow.

Here’s what I’d like to do: have the entire string be bright at the end, and dimming to black at the other end, like a gradient. I can do it with a static string, but I can’t figure out how to do it when I’m pushing pixels ahead like that. Any ideas? Do I need to think of possibly using a mask and apply it each time I move the pixels?

If I understand your problem correctly,

you could fade them while/after moving them one step forward
Just add after this line:
leds[px] = leds[px - 1];
// new code
leds[px].nscale8(255-(255/NUM_LEDS));

if you have more than 255 leds this will not work (no fading), but for NUM_LEDS < 255 it should make the colors fade to black.

Not quite. So there are 48 LEDs on the string. I want the ones at the end to be at full brightness and the ones at the other end to be faded out to black. When I push the data, the fade also moves with it. For example led[48] will be at full brightness where led[47] is a little less. When I push the string, led[48] now contains the values that are in led[47] … which is not full brightness. Eventually the values of led[0] will reach the last LED, and it will be off completely.

So unless I refill the entire string with new data and then reapply the fading, I can’t think of another way of doing it. And if I’m going to refill it every cycle, I won’t have to push the pixels forward. I don’t know what’s better to do, refill and reapply the fade effect, or just refill with the correct values every time.

if you “only” have 48 LEDs, I would go with two led arrays - one with the full brightness values and the other with the faded values (that gets pushed to the LED strip).
This should work out fine, if you have enough RAM in your microcontroller :wink:

Try running the code above. Stick it in a loop() that’s constantly calling it and you’ll see what it does. A color starts at pixel 0 and traverses the string to pixel 48. Right now, the entire thing is at one set brightness. I want it to be a gradient instead, so that a pixel, any and all pixels, start at position 0 with a brightness of 0 and traverses the string increasing in brightness till it reaches position 48 where it’ll be at full brightness.

That in and by itself can be written out in a simple loop, however when you are constantly moving the pixels like I am above, thing are always changing. A pixel does not stay in the same spot, thus its brightness is constantly changing as it gets pushed further along the string. Not to mention that every 6 pixels will be the same hue but not the same brightness, and every 12th is a different hue. You really need to run the code to understand what it’s doing.

I think I get what it is doing now and what you are trying to make it do.

try this code (untested):

// add this after the CRGB leds[NUM_LEDS]; line:
CRGB ledsTwo[NUM_LEDS]; //this is the helper array that keeps all the LED values at full brightness

void HSVRainbow() {
static uint8_t hue = 0;
if (millis() - patternLastRun > 10) {
if (!off) {
ledsTwo[0] = CHSV(hue, 255, 255);
} else {
ledsTwo[0] = CHSV(0, 0, 0);
}
cntr++;
if (cntr > 5) {
cntr = 0;
off = !off;
hue += 15;
}
for (int px = 0; px < NUM_LEDS; px++) {
// copy leds from ledsTwo to leds
leds[px] = ledsTwo[px];
// dim leds from 0=black to NUM_LEDS=255
leds[px].nscale8(255.0/(NUM_LEDS-1) * px);
}
LEDS.show();
for (int px = NUM_LEDS - 1; px > 0; px–) {
ledsTwo[px] = ledsTwo[px - 1]; // shift ledsTwo by 1 pixel
}
patternLastRun = millis();
}
}
//END OF CODE

the CRGB array “ledsTwo” now holds the full brightness RGB values of all LEDs, all changes in the loop are made to the “ledsTwo” variable.
Just before the values get pushed to the LED strip, we copy the values into the “real” leds variable and dim all the lights according to their position (first LED dark, last LED at full brightness)

I hope you understand the changes that I made to the code and my assumptions of what you are trying to achieve are correct :slight_smile: