For a recent project, I wanted to build a variable-brightness LED lamp, using an MSP430 to convert the linear slide potentiometer input into a PWM signal to drive the LED. Unfortunately, directly scaling the 10-bit ADC value to a 16-bit PWM duty cycle does not result in a linear apparent brightness response due to the eye’s (approximately) logarithmic response.
There are several ways to accomplish this conversion in an embedded system, with different trade-offs:
- Use floating point math and powf() from math.h
- Use a 1024-element lookup table of pre-computed values
- Use a smaller lookup table with interpolation
- Use an approximation that trades accuracy for speed & size
Implementation of approximation algorithm
I decided to try the last option and use the fact that 2^n is equivalent to 1 << n, since bit-shifts are much quicker than multiplication and division.