I just installed my new fastLED based controller (replacing the previous non-wifi feather m0).

I just installed my new fastLED based controller (replacing the previous non-wifi feather m0).

I noticed something that is a bit odd. I’m displaying an HSV rainbow - nothing odd there, brightness is steady at about 33% for all the Hues. If I reduce saturation, so tending towards white, the brightness goes up, until at 0 saturation, the LEDs are all full on (255,255,255), and the strip is three times brighter than at 255 saturation.

Is this expected behavior? I thought the brightness would stay constant with varying hue (which it does) and saturation (which it doesn’t).

I can finagle it by varying brightness (level/value) with saturation, but isn’t the HSV model supposed to avoid the need for dealing with these kind of issues? Or am I missing something?

Thanks,

Someone asked for my code- Here it is:

#include “helper_functions.h”

void parse_rainbowCycle() {
//Function to parse global variables for rainbow mode
display_message(“Rainbow Cycle Mode”);
previous_display_mode = display_mode;
display_mode = RAINBOWCYCLE_MODE;
display_blank = false;
mode_from_mqtt = false;
}

void do_rainbowCycle() {
if(mode_from_mqtt) parse_rainbowCycle();
static CEveryNMillis UpdateTime(timing/fps);
static uint8_t hue;

if(UpdateTime) {

uint8_t beat = beatsin8(fps*60, min_brightness,saturation,0,0);
//progression can be SHORTEST_HUES, LONGEST_HUES, FORWARD_HUES, BACKWARD_HUES
fill_gradient(&leds[0], min_led, CHSV(hue,beat,max_brightness), max_led, CHSV(hue+255,beat,max_brightness), FORWARD_HUES);

hue+=hue_increment;

show_leds();
UpdateTime.setPeriod(timing/fps);
}
}

Hmmm… anyone know what code markers work here (if any?)

OK, update: here is my constant brightness with varying hue and saturation code. It is UGLY.

I tried to find a mathematical solution, the closest I can get is this:

uint8_t calc_bri = qadd8((((uint16_t)beat*5)/8),148);

(where beat is saturation). saturation vs brightness seems to be linear, for a fixed hue, but hue vs saturation vs brightness is not. (I did resort to graphing the response by the way).

This works for a fixed hue (in this case 0), but goes out the window as soon as you start varying the hue. The brightness seems to depend on the amount of green in the pixel, so you have to calculate the amount of green for the specific hue, saturation, brightness - and then it’s not particularity linear on the rainbow setting. I couldn’t find a mathematical fit, so I had to go with the brute force method instead - ugh!

void do_rainbowCycle() {
if(mode_from_mqtt) parse_rainbowCycle();
static CEveryNMillis UpdateTime(timing/fps);
static uint8_t hue;

if(UpdateTime) {

uint8_t beat = beatsin8(fps*60, min_brightness,saturation,0,0);
//progression can be SHORTEST_HUES, LONGEST_HUES, FORWARD_HUES, BACKWARD_HUES
uint8_t chv1_brightness = max_brightness;
uint8_t chv2_brightness = max_brightness;
uint8_t target_brightness = max_brightness/3;
CRGB rgb_colour1 = CHSV(hue,beat,chv1_brightness);
CRGB rgb_colour2 = CHSV(hue+255,beat,chv2_brightness);
uint8_t colour1_brightness = qsub8(rgb_colour1.getAverageLight(), target_brightness);
uint8_t colour2_brightness = qsub8(rgb_colour2.getAverageLight(), target_brightness);
while(colour1_brightness > 0) {
  chv1_brightness--;
  rgb_colour1 = CHSV(hue,beat,chv1_brightness);
  colour1_brightness = qsub8(rgb_colour1.getAverageLight(), target_brightness);
}
while(colour2_brightness > 0) {
  chv2_brightness--;
  rgb_colour2 = CHSV(hue+255,beat,chv2_brightness);
  colour2_brightness = qsub8(rgb_colour2.getAverageLight(), target_brightness);
}


fill_gradient(&leds[0], min_led, CHSV(hue,beat,chv1_brightness), max_led, CHSV(hue+255,beat,chv2_brightness), FORWARD_HUES);

hue+=hue_increment;

show_leds();
UpdateTime.setPeriod(timing/fps);

}
}

If anyone can come up with a better method than this please post!

Can you show your code?

If you are using fill_rainbow, remember that it sets full saturation and full brightness.

I’m pretty sure that’s intended, otherwise it would be impossible to achieve full brightness white through HSV.

What you’re seeing sounds right to me. Pure red is FF0000, meaning that the red led is full on and the blue and green less are totally off; that is roughly 1/3 on, and thus 1/3 power. We’ve designed the hsv model we selected to keep power usage and brightness pretty much constant regardless of hue.

As you desaturate though, you are adding more white, lighting the other less more. That’s what you’re seeing I think.

I sometimes think about offering a constant-brightness conversion that kept power the same even as saturation goes down. That would make “white” 0x555555, which might be useful in some cases, but then I’d also want a separate way of controlling the max brightness. I’ve prototyped a couple of different conversions, but I’m not ready to replace the current one just yet.

Glad to hear we have another color-hacker here!

(Also, there are no code markers that work here which is why I am continually asking people to use http://gist.github.com or pastebin)

No code markers? That’s a pita. Ok so I’ll have to finangle it via some cunningly unreadable code…
Thanks all.

Just posted my not-so-cunning unreadable code…

Again - there are no code markers here - which is why as I mentioned above, am “continually asking people to use http://gist.github.com or pastebin” for posting of code.

I’m no longer going to look at/debug/advise on code beyond short snippits that’s pasted in g+ posts or comments. This goes doubly so for someone who goes ahead and does that after I ask them to use something like gist or pastebin.

Well no-one asked me, you made a comment about “asking people”, I assumed you were talking about large sections of code, people are unlikely to use github to post one short routine.