LED brightness vs PWM

Thread Starter

TheComet

Joined Mar 11, 2013
88
Hey all,

I'm working on a 16x16 LED RGB Matrix (picture here), and have come across the following problem.

LED brightness is NOT linear to the human eye. This is because of two reasons.

  1. Forward current vs brightness isn't linear
  2. The human eye is logarithmic

My question is, what exactly is the relationship between a PWM signal and perceived brightness, and how do I calculate a look-up table to compensate with the correct duty cycles?

Thanks,
TheComet
 

THE_RB

Joined Feb 11, 2008
5,438
There's no easy way to calculate it.

What I do is test it. Make the PWM adjustable with a display to show the PWM %. It helps if you can have two settings, and a switch to change instantly between the two.

Then find the PWM where your eye thinks it's "50% brightness". Write that down.

Then switch between that setting and one where your eye thinks it is "25% brightness", write that down.

After you have a few key points you can create a curve in a table that more or less matches those points.

Pay more attention to the low brightness end of the table, that is where it is more critical.
 

MMcLaren

Joined Feb 14, 2010
861
... what exactly is the relationship between a PWM signal and perceived brightness, and how do I calculate a look-up table to compensate with the correct duty cycles?
Based on discussions on Forum Microchip long ago, the relationship seems to be anti-logarithmic. I've had good results using a gamma correction array for linear brightness control and smooth fades. The gamma array index is the linear brightness input (0 to 63 steps, 0 to 99 steps, etc.) and the matching array element is the PWM duty cycle output.

To build the gamma array for my embedded programs I wrote a simple program using the free JustBASIC language. Here's the program listing and a sample output;

Rich (BB code):
 '  Leo Bodnar's 'antilogarithmic'
 '  gamma correction algorithm (Mike, K8LH)
 '
 '  JustBASIC (free) interpreter
 '
 Input "Gamma array size: "; arraysize
 Input " Total PWM steps: "; width
 Input "Gamma correction: "; gamma       ' try 0.5 to 1.0
 Input "Entries per line: "; entries     '

 FOR index = 0 to arraysize-1
    dcyval = INT(width^(((index+1)/arraysize)^gamma)+.3)
    if(index = 0) then
      dcyval = 0
      PRINT
      PRINT "  DW ";
    else
      if(index MOD entries = 0) then
        PRINT ","
        PRINT "  DW ";
      else
        PRINT ",";
      end if
    end if
    if(dcyval < 100) then print " ";
    if(dcyval < 10) then print " ";
    PRINT dcyval;
 NEXT index
 PRINT
 PRINT
 REM CLOSE
Rich (BB code):
Gamma array size: 100
 Total PWM steps: 255
Gamma correction: .67
Entries per line: 10

  DW   0,  1,  1,  2,  2,  2,  2,  3,  3,  3,
  DW   3,  4,  4,  4,  5,  5,  5,  6,  6,  6,
  DW   7,  7,  8,  8,  9,  9, 10, 10, 11, 12,
  DW  12, 13, 14, 15, 15, 16, 17, 18, 19, 20,
  DW  21, 22, 23, 24, 25, 27, 28, 29, 31, 32,
  DW  34, 36, 37, 39, 41, 43, 45, 47, 49, 51,
  DW  53, 56, 58, 61, 63, 66, 69, 72, 75, 78,
  DW  82, 85, 89, 92, 96,100,105,109,113,118,
  DW 123,128,133,138,144,150,155,162,168,175,
  DW 181,189,196,203,211,219,228,236,245,255
I copy and paste the gamma table data from the JustBASIC console window into my embedded program and format it as an array.

The "gamma correction" parameter defines the shape of the anti-log curve. Test gamma arrays using different correction values between 0.5 and 1.0 to match the characteristics of your LEDs and driver circuit.



Good luck on your project.

Cheerful regards, Mike
 
Last edited:

atferrari

Joined Jan 6, 2004
4,770
where your eye thinks it's "50% brightness".
Hola Roman,

Please do not take me wrong but all what is related to "perceived" whether sound, light, vibration is always subjective. And thats why, probably you suggest the method above.

Isn't a simple formal / objective way to say what is 50 % percent, or 25% or whatever?

I presume that your reply could say something about what is / is not practical...

Thanks
 

JMac3108

Joined Aug 16, 2010
348
You use a Luminance meter that measures in cd/m^2 (nits). These are commonly used to measure LCD display brightness and can be had for a few hundred bucks up to thousands. They often have a feature to correct for the spectral response of the human eye.

Other than this ... you're back to the other methods described.
 

THE_RB

Joined Feb 11, 2008
5,438
Hola Roman,

Please do not take me wrong but all what is related to "perceived" whether sound, light, vibration is always subjective. And thats why, probably you suggest the method above.

Isn't a simple formal / objective way to say what is 50 % percent, or 25% or whatever?
...
Yes for sure it depends on the viewer, and also depends slightly on the ambient conditions (room lighting intensity).

And unfortunately it also varies between Red, Green and Blue LEDs even in the same RGB LED package! So you might need 3 different curves.

But assuming you have decent colour vision and are methodical, it's not hard to judge a LED at "full" or "half" brightness, especially if you have a switch to quickly switch between back to back settings.

Once you have done some tests and made a curve (like MMcLaren suggested) you can use it on other projects, but personally I like to check any new LED type and make sure the curve fits that new LED type, AND the application (ie room lighting etc).
 

atferrari

Joined Jan 6, 2004
4,770
You use a Luminance meter that measures in cd/m^2 (nits). These are commonly used to measure LCD display brightness and can be had for a few hundred bucks up to thousands. They often have a feature to correct for the spectral response of the human eye.

Other than this ... you're back to the other methods described.
Thanks. If not knew, I "suspected" that.
 

Thread Starter

TheComet

Joined Mar 11, 2013
88
Thanks for the help so far!

@ MMcLaren

I plugged your formula into my code, and it seems pretty accurate. May I ask, where did you acquire that formula?

All

You use a Luminance meter that measures in cd/m^2 (nits).
Based off this quote, and based off the assumption that luminance is directly proportional to the LED's forward current (which it isn't, but it's close to it as long as the range is small), wouldn't it make sense to assume that brightness is (1/sqrt(2))^dt?

TheComet
 
Top