Is there a way to set the individual brightness level of a specific element

Is there a way to set the individual brightness level of a specific element in the leds[x] array? I see there is a leds[x].setHue(x) call but not a setVal(x)? What’s the best way to do this? I don’t want to change the color but I do want to adjust the brightness of individual LEDs independent of each other using the HSV model.

So when you originally put a color into it, if you’re using CHSV, then you can just adjust the Value that you’re using.

If there’s already a color in a pixel and you want to scale it down, you can use "fadeLightBy or “fadeToBlackBy” which will perform one downscaling operation.

leds[i].fadeToBlackBy( 10 ); // dims by 10/256ths

Check out this wiki page

and scroll down to “Dimming and Brightening Colors” for more info!

I’m working on code that assumes there is something else going on in the led array and I need to reduce its brightness but still have it operating while I layer another sequence on top, and in that case I want to individually downscale the first sequences lights.

Is there any way where I can set an absolute brightness value per pixel. You have a function to apply it to the entire led array, but not individual pixels?

Is there any formula I could use to re-calculate the RGB or hsV values given that I don’t necessarily know the color of the pixel and just want to reduce brightness to a set level (as opposed to downscaling by a percent)?

So do you want something like “scale each individual pixel down independently so that the total light output of each pixel is no more than X”? If so, that will have the effect of unevenly levelling-out bright pixels and dim pixels: the bright ones would be scaled down a lot, the dim ones wouldn’t be scaled down much at all.

I suspect that what you’re going to wind up using is fadeLightBy or fadeToBlackBy on the whole array. You probably want to calculate the scale-down factor in some intelligent way, like by scanning down the array once to see how bright it is before the scale-down, calculate the scale-down factor you want, and then apply it evenly to everything.

Perhaps if you could share the code you’re writing – or much more specific description of the numeric values and ranges you’re shooting for – it’d be easier to give specific help, which I’m happy to do.

I’m simply looking for something like:
LEDS.setBrightness(x)
that instead of working on the whole array, will allow me to set brightness/value for a single element of the array.

You have: leds[x].setHue(x)
It would make sense to also have a corresponding: .setSat() and .setVal() would it not?

The problem with using the Fadeby functions is that this would be implemented within a loop and I only want to fade the pixels one time, not continue to decrement them. That’s why I need to reduce brightness to a set level.

setHue() also sets the saturation and brightness, both to 255. It’s basically the same as
leds[i] = CHSV( newHue, 255, 255);
It doesn’t ‘change the hue while leaving the brightness and saturation the same’.

I can help with your code, but I need to know one thing specifically. Imagine you have two pixels already set, with these values:
leds[0] = CRGB( 255, 0, 0); // full red
leds[1] = CRGB( 32, 0, 0); // dim red

If you performed this new hypothetical “setBrightness” operation on them, with a value of (say) 128, what numeric values would you want the values of those two pixels to be afterwards? If you tell me that, I can help you get there code-wise.

Thank about it like this… there is background music on a speaker system in the supermarket. When someone wants to make an announcement, rather than cut the music off, its volume is reduced while the announcement is made, then kicked back up when it’s over. I want to do the same thing visually with LEDs. So I want the background always going on for continuity, but drop it down to a certain level when I lay the new sequence on top.

There is probably a way to use various routines that exist that relatively fade pixels, but I was hoping to be able to alter the led array in a single swoop while I’m writing the overlay sequence. And for that, the ability to arbitrarily set the brightness value of an individual pixel to a specific absolute level, would come in handy.

Yep, I get that. I do that all the time in my code.

Did you see the question I asked about what numeric RGB values you want as output from this function? (Or did our posts cross time-wise?)

If you want to ‘dim’ a pixel down to 25% of it’s existing value,
leds[i].fadeLightBy( 192 ); // reduce by 75%
will do it. That’s a synonym for
leds[i].nscale8_video( 64 ); // scale down to 25%

Is the problem here with adjusting one pixel down numerically is that it then loses data, and you can’t scale it back up to the exact same original value?

If that’s the issue, then you need to have a ‘source’ buffer that keeps the original pixel values and an output buffer (leds[]) that has the scaled-down versions.

Ahh yea, our posts crossed each other and I didn’t see them… let me respond to your previous post… sorry about that.

First, I didn’t know that .setHue also changed the other values… ahhh

You said: " leds[0] = CRGB( 255, 0, 0); // full red
leds[1] = CRGB( 32, 0, 0); // dim red

If you performed this new hypothetical “setBrightness” operation on them, with a value of (say) 128, what numeric values would you want the values of those two pixels to be afterwards? If you tell me that, I can help you get there code-wise."

In the above case, I would expect both pixels to be dimmed relatively. I am assuming HSV values are percentages (1=1/256 and 255=100%) So that setting to 128 would in effect make leds[0]=CRGB(128,0,0) and leds[1]=CRGB16,0,0)

Is that formula the best way to handle dimming a background sequence?

Now that I think about it, I guess I could use FadeBy… assuming the underlying sequence was always refreshed to its normal brightness before the overlay was called. I keep forgetting that brightness is, in-effect a color itself and I can’t mess with it independently. It’s weird how we have a distorted view of how these things work.

I think you’re onto a good track there: if the underlying animation is being re-drawn into the leds[] buffer every frame, then this one line will drop the brightness down by whatever fractional amount (0-255) you wish; 64 would be a 1/4 reduction in brightness, 192 would be a 3/4 reduction.

fadeLightBy(leds, NUM_LEDS, fadeByAmount);

So your overall flow would be

for every frame:

  • draw background animation into leds[]
  • if there is a ‘foreground’ to put on top then…
    • fadeLightBy( leds, NUM_LEDS, 192);
    • draw ‘foreground’ into leds, using “+=” operator

That last item there, about using += is so that that foreground adds on top of the background:
leds[i] = background color;
leds[i].fadeLightBy( 192); // dim it down
leds[i] += foreground color; // ADDS values (vs replacing)

Progress?

Thanks! I am uploading a video now showing the difference between just tossing a sequence on top and what I call “ducking” the background. In audio engineering this is a term where you compress background tracks relative to something you want to bring to the foreground. I’ll post a link that demos what I’m doing. My next step is to make the ducking more dynamic, and relative to specific areas around the foreground sequence and not simply the whole array.

Very nice! And you’re exactly right: what you’re doing is “light ducking”!

And you’re also demonstrating in that video something super useful to design with: it’s often the contrast between light levels that makes something look brighter, not just the absolute light output. Letting everyone’s eyes acclimate to one level and then spiking up bright looks brighter than running max brightness all along.

Also: eyes are non-linear. They’re quadratic-ish. So 50% power looks like about 75% brightness. 25% power looks about 50% brightness.

And from the video it looks like you’re going to build some cool effects! Thanks for sharing the video – and post your other experiments and progress as you go!

I can see there’s a lot of similarities when dealing with light as with sound. Now the idea of always generating light at max brightness seems about as appealing as always listening to music at the loudest volume. Everything washes itself out at high intensities and it’s much better to work subtractively than additively. Thanks a lot for the insight Mark! :slight_smile: