I have a project where I am turning Leds on and off with midi signals
midi note on triggers:
void led01on() {
leds[1] = CRGB::Red;
FastLED.show();
}
midi note off triggers:
void led01off() {
leds[1] = CRGB::Black;
FastLED.show();
}
I would like to have, for note off, a fade out from red to black instead of going straight from red to black. Which is the simplest way to write this?
First, I’d move the calls to “FastLED.show()” out of the On and Off functions, and just put one call to FastLED.show() in the main loop() function.
Then I’d set the ‘on’ notes to CRGB(255,0,0) aka Red.
And I’d set the ‘off’ notes not to black, but to CRGB(200,0,0) aka dimmer red.
And I’d add a function that iterated through all the leds, and for each one ‘faded’ it a bit if it was lit, but less-than-fully-bright:
void fadeDimmingPixels() {
for( uint16_t i = 0; i < NUM_LEDS; i++) {
if( leds[i].r > 0 && leds[i].r < 255) {
leds[i] -= CRGB( 5, 0, 0);
}
}
}
Then call fadeDimmingPixels() every time through the main loop() function, just before the call the FastLED.show();
My two cents. Let us all know what you experiment with and what you come up with!
thank you so much mark to provide a solution while helping me making my code cleaner!!
It was not that easy because there were other things in the code that I ignored when sharing, but exactly that forced me to understand better what I was doing.
I will certanly “show off” my work as soon as it is ready!
thanks again!
@Mark_Kriegsman
here the surprise:
the method you described works very nicely with RGB pure colours. I mean, is very easy to dim evenly from red (255,0,0) to black (0,0,0) substracting (2,0,0) until it gets black. But it got more complicated when I tried it with fuchsia (255,0,128). I tried substracting (2,0,2) which obviuosly works but it also turns the color to red towars the end, and (2,0,1) leaves a little bit of blue on at the end.
so, I convert everything to hsv, where fuchsia is CHSV(330,255,255) and my note off is then CHSV(330,255,254). For me it was clear that now I had to substract CHSV(0,0,2), but I got the following error:
‘struct CRGB’ has no member named ‘v’
Then, what I was declaring at the beggining of the code as:
CRGB leds[NUM_LEDS];
I changed it for:
CHSV leds[NUM_LEDS];
and the error is gone, but the sketch is stucked in the compiling process…
I also changed in the void fadeDimmingPixels() all the if(leds[i].r for if(leds[i].v
what could be going on?
Uh. Yah. Ok so this is more complicated than I have time for before I make dinner for me and the kid. BUT try this:
Go back to RGB. then: Instead of subtracting a fixed amount from the pixel inside the IF, do this:
leds[i].fadeToBlackBy( 5 ); // proportional dimming
ok. I tried the fadetoblack method that works just fine.
BUT now I would like to understand what is going on with CHSV colours!
I changed the hue to a value between 0 and 255, but the compiling continues to fail.
without the function “fadeDimmingPixels”, the code works alright when I use CRGB leds[NUM_LEDS];. If I use CHSV leds[NUM_LEDS]; it fails to compile. But when using CRGB leds[NUM_LEDS]; it says that “‘struct CRGB’ has no member named ‘val’ or ‘v’”
Two things going on there:
First, FastLED.addLeds requires a CRGB array, because that’s what the LED strip actually is: an array of RGB LEDs. So if you try to change your main leds array to CHSV, it’s not going to compile.
Second, CRGB’s members are r g and b (aka red green and blue), and CHSV’s members are h s and v (aka hue sat/saturation and val/value). You can’t access the “val” of a CRGB because it doesn’t have one. So probably you have code that’s trying to access “leds[i].val” after you’ve (correctly) declared leds to be CRGB.
There’s more detail on the whole CRGB vs CHSV business here: https://github.com/FastLED/FastLED/wiki/Pixel-reference
Glad the fading is working, too!
thanks mark. I understand this 2 issues. I was already there while trying things out and I was also checking our the wiki reference, but this still leaves me with one important question:
how do I use CHSV objects with a led strip?
For now and for my actual project, this is sorted out, since the fadetoblackby method works correctly, but if I think of a project where I want a change of hue instead of a fade to black, obviously CHSV is much simpler to apply.
Great question.
The crispest answer is that if you have the RAM available, you maintain a CHSV ‘master’ array, and convert it into the (required) CRGB array just before you call show:
CRGB rgbleds[NUM_LEDS];
CHSV hsvs[NUM_LEDS];
void setup() {
…
FastLED.addLeds<WS2811, DATA_PIN, GRB>(rgbleds, NUM_LEDS);
}
void loop() {
…
// convert all hsvs into rgbs:
hsv2rgb_rainbow( hsvs, rgbleds, NUM_LEDS);
// send the actual rgbs to the physical led strip:
FastLED.show();
}
Sometimes I name the CHSV array “pixels” (instead of hsvs), but that’s just a personal choice.
If you don’t have enough RAM to do this, all the other options are more complicated – and worthy of a new top-level discussion thread! If you hit that, let’s start a new thread, as LOTS of people will probably chime in.
Loud and clear, but now when I try to
if(hsvs[11].v > 0 && hsvs[11].v < 255) {
hsvs[11] -= CHSV(0,0,2);
}
it complains that
no match for ‘operator-=’ (operand types are ‘CHSV’ and ‘CHSV’)
Yeah, “subtracting one HSV color from another” isn’t well defined. (Or in this case, defined at all!)
Try:
//Subtract two from v,
//but guard against going negative
//or wrapping around.
hsvs[i].v = qsub8( hsvs[i].v, 2 );
if(hsvs[i].v > 0 && hsvs[i].v < 255) {
hsvs[i].v = qsub8(hsvs[i].v, 2);;
}
does the job
thanks mark very much. I have a lot to reflect upon!
when you say that “subtracting one HSV color from another isn’t well defined. (Or in this case, defined at all!)”
This means that the library is not ready to do this, but it is totally possible, as we did it already when substracting CRGB?
Well the library can’t do it right now, true.
But also: it’s unclear what it should mean, especially with respect to hue.
What is blue minus red, and why?
Math on V make sense though.