I'm building a keyboard light with AVR micro controller.
There are two buttons, BRIGHT and DIM, and a white LED.
The LED isn't really linear, so I need to use a logarithmic scale (increase brightness faster in higher values, and use tiny steps in lower).
To do that, I adjust the delay between 1 is added or subtracted to/from the PWM compare match control register.
while (1) {
if (btn_high() && OCR0A < 255) OCR0A += 1;
if (btn_low() && OCR0A > 0) OCR0A -= 1;
if (OCR0A < 25)
_delay_ms(30);
else if (OCR0A < 50)
_delay_ms(25);
else if (OCR0A < 128)
_delay_ms(17);
else
_delay_ms(5);
}
It works nice, but there's a visible step when it goes from one speed to another. It'd be much better if the delay adjusted smoothly.
Is there some simple formula I can use? It must not contain division, modulo, sqrt, log or any other advanced math. I can use multiplication, add, sub, and bit operations. Also, I can't use float in it.
Or perhaps just some kind of lookup table? I'm not really happy with adding more branches to this if-else mess.