# Non-linear LED Response Workaround?

I want to create an effect that has a pixel LED slowly going from black to orangered to mimic a component slowly getting red hot.

In theory it’s simple enough, but the results aren’t quite as realisic as I’d like.

The issue seems to be that brightness increases are non-linear, so rather than the brightness emerging really slowly, it’s nothing, nothing, nothing, on quite a bit, then on full.
My code is below and I’ve set the duration to 40,000 which is already quite long.

I guess my question is can we build a style that accounts for the non-linearity of the LED? For instance, can we set it to go from Rgb<0,0,0> to Rgb<20,2,0> over 40,000 milliseconds, then Rgb<20,2,0> to Rgb<125,15,0> over 10,000 ms? Is there way of going up in stages like that? And would it work?

Any thoughts welcome.
Here’s the code I’ve been using:

Try the “Metal Forge” Heat Up Ignition Effect in my library under Ignition Options on the Enhancements screen (there’s a corresponding Retraction Effect too).

The problem here isn’t that the LED is nonlinear, because it is. The problem is that it is linear, but human eyes are not. Human eyes have a response that is closer to response = \sqrt[3]{brightness} What this means is that if you increase a black led by a tiny amount, it looks like a big change. If you increase a white led by the same amount, it does not look like a big change.

Because neopixels are linear, and only have 8 bits of precision, the darkest we can make it without turning it off, is 1/255th of it’s maximum brightness. Unfortunately, this still looks fairly bright to the human eye. ProffieOS tries to work around this by doing dithering, which adds some additional levels by rapidly switching the LED between 0 and 1 values, but even that is not enough at very low levels.

There are a couple of ways to possibly get this to work.

1. Cover up the led with some tape or something, then use higher values. By reducing the maximum brightness in this way, we’re also gaining more precision in absolute brightness.
2. Use regular LEDs instead of neopixels. The ProffieOS PWM has 32768 levels, which should be enough.
3. Use dotstar/Apa102 LEDs. These leds have more bits controlling the brightness, leading to much more accuracy in the lower levels. (Not entirely sure how much, because I haven’t tried it.)

To gain more control over the curve and colors, you probably want to use TrConcat<> to concatenate multiple transitions together.

1 Like

Thanks so much guys - legends as always!
I see what you mean about the nature of LED light completely Prof - makes perfect sense. And for my purposes, as I’ve just learned from breaking down Fernando’s code, Trconcat<> was indeed the answer. I broke it down to four steps, with the first literally just going from zero to Rgb<3,0,0> over 4,000 milliseconds, which worked pretty well. The code is below.

I’ll post up a video when I’ve had a chance to shoot one. The way I’ve used it is a really fun effect on this particular hilt.

Many thanks again. In both your debt as always.