Higher Precision DMX Lights <or> Non-Linear DMX Lights


I have created an Arduino device to take in UDP/IP commands over the network and use that data to control DMX lights. The UDP commands can call for a curve (go from brightness: 0 to brightness: 255 over 8 seconds).

These curves looked relatively weird. They faded up quickly at the low light levels and it looked like no brightness change was happening at the brighter levels. I found a few resources saying that the perceived brightness of lights is different from the actual brightness (lumens/brightness level). The at lower levels we are more sensitive to light and at higher levels we are less sensitive. This explains that, to the naked eye, hardly any change was visible at the higher light levels.

A few resources* said the the relationship between lumens/actual brightness is:

P = sqrt(A / 255)

Where P = the perceived brightness (0-255 scale)
and A = the actual brightness (0-255 scale)

The program linearly calculates what the perceived brightness SHOULD be based on the time elapsed and parameters of the fade. So I take what the perceived brightness SHOULD be and square it before printing it out. This is because the perceived brightness squared should equal the actual brightness, or brightness level we need to print out.

The problem with this is that, at low light levels, the slope of this filter is so low (given its quadratic nature) that, given a, say, 8 second fade, the device may only change by a rate of 1 step per second early on. This makes it so the fade looks very choppy. (Furthermore, at lower levels, again, our eyes are more sensitive, so the steps are even more easier to notice.)

To remedy this problem there are of course software options that could be implemented (though they would make the quadratic function imperfect), but I am curious:

  1. What is holding the hardware back from have more than just 0-255 steps? In other words, could new hardware be bought that could allow a fade from 0-1020? This added precision would allow there to be enough steps that the the steps would not be visible at the early brightness levels of the filter. Is this something limited by the lights? If there are lights like this, I am assuming they would need something like, 4 DMX channels per color per light. I only have 16 channels of 4 RGBW lights (1 channel per color per light), and I know DMX can control 512 channels of 0-255 precision. So, for example I could have 4 channels of 0-255 precision per each of the 4 colors per each of the 4 lights. This would result in each color having 4255 or 0-1020 precision and would use up 44*4 channels or 64 channels instead of the 16. Is this a thing?

  2. I do not think the following would be true, but I am going to ask anyways: Is the light controller, or in this case, Arduino DMX Shield, what is holding the system back from adjusting the lights more precisely than 0-255? Alternatively, is the DmxSimple Arduino library what is holding this back? I assume the lights are the limiting factor from this precision, not the controller, but, again, I am not 100% sure.

  3. An alternative hardware solution I can think of is if the lights themselves were scaled non-linearly (perhaps logarithmically or quadratically). Are DMX lights sold that are designed to, when, say, changed from 100/255 brightness level to 200/255 brightness level, change from 39% to 78% perceived brightness instead of 39% to 78% lumens, or actual brightness? From what I’ve read, these lights would need to be non-linearly scaled. Again, do these types of DMX lights exist?

Thanks for any advice.

FYI: In case you are curious as to how I have DMX lights and have spent time programming a controller for them but do not know much about the DMX system, it is because I am programming these lights for someone else, not myself, and they own the lights, not myself.

Edit: *Here is the link for one of the two sources supporting this claim:

P = sqrt(A / 255)

Where P = the perceived brightness (0-255 scale)
and A = the actual brightness (0-255 scale)

With A at its maximum value of 255, then P would be sqrt(255/255) = sqrt(1) = 1

To give P = 255, A would need to be 255 * 255, which is bigger than 255...

Perhaps you should double-check that formula.

Yes, the human eye is not linear in its perception of brightness. I don't know if that formula is a correct representation, though.

I don't know much about DMX. Almost nothing. Is DMX limited to 8-bit resolution?

With ATmega based Arduino, digitalWrite() function is normally 8-bit resolution. I understand it's possible to achieve 10-bit with some output pins, but not all.

Arduino based on other, more modern chips, like esp8266 can output 10-bit pwm on any pin.

Human perception of brightness and loudness are logarithmic. Not sqrt. With standard DMX512
channels of 8 bit linear resolution you won't get smooth brightness control. A 16 bit paired channel is needed
and the curve needs to be exponential to correct for the eye's logarithmic sensitivity.

Some DMX devices will incorporate an exponential slope internally I suspect, many may
simply map the DMX value directly to PWM duty cycle, ie have a linear reponse. I'd check
the data for the lights in question, they may be able to have alternate curves programmed?

With internal exponential curve 8 bits is enough for good brightness control.