> Hi all. I've been playing around with software PWM controlling some > LEDs. Problem is, as the eye's response to brightness isn't linear, when > I simply control the LEDs brightness using an 8 bit value (with no > compensation) they don't appear to dim smoothly. So my thought was to > take the 8 bit value, use it as an index into a lookup table which would > give me a higher bit value (ie a 12 or 14 bit). > > Here is the problem (as I see it anyways). If I increase the bit > resolution of my PWM, the frequency will have to go down (as the PIC is > already running at full speed. yes, I could go to an SX chip...I know). > So, is there a resolution vs speed balance that anyone has reached that > gives optimal frequency and smoothness of the dimming? Also, how do you > choose the values for the lookup table? Most commercial theatrical > dimmers use a "modified S curve" which is essentially the integral of > the area under a sine wave (I think). I'm sure if I had Maple or > something (and knew how to use it) I could divide the area into 256 > sections and come up with the proper values for the lookup table. But > since I don't have access to this high powered math software, what are > my options? Plotting out by hand seems only an invitation for > frustration. The preceived brightness is essentially the logarithm of the actual brightness, and the actual brightness of LEDs is reasonably linear to current. First you have to decide what dynamic output range you can produce, then map that to the non-zero intended brightness values logarithmically. Since the log will never let you get to zero, you arbitrarily assign 0 input value to LED completely off. Note that you will lose resolution in the conversion, but how many different brightness levels do you really need? Let's do an example. You are using 8 bit PWM output, so the linear brightness can vary from 0 to 255, with 0 completely off and 255 completely on. The dynamic range of the non-zero output values is 255/1. Now map this range logarithmically to the non-zero range of input number. If the desired perceived brightness values are 0-100, then 1-100 maps to output values 1-255 lograithmically. In other words, each single step up in the 1-100 range increases the output value by a fixed *multiple* (fixed increment would be linear). There are 99 steps from 1-100 to cover the dynamic range ratio of 255. The step multiple is therefore the 99th root of 255, or StepRatio = DynamicRange ** (1 / NSteps) = 255 ** (1 / 99) = 1.057568 The output value resulting from each non-zero input value is then: output = StepRatio ** (input - 1) = 1.057568 ** (input - 1) Since logarithms don't go to zero, you arbitrarily assign input 0 to output completely off. So here are a few sample input and output values: INPUT (0-100) OUTPUT (0-255) 0 0 1 1 2 1.06 3 1.12 4 1.18 5 1.25 10 1.65 20 2.90 30 5.07 40 8.87 50 15.53 60 27.18 70 47.56 80 83.25 90 145.70 100 255.00 Of course you will have to round the output values above. ***************************************************************** Embed Inc, embedded system specialists in Littleton Massachusetts (978) 742-9014, http://www.embedinc.com -- http://www.piclist.com hint: The PICList is archived three different ways. See http://www.piclist.com/#archives for details.