--- /dev/null
+title: RGB Lamp Led Driver
+linktitle: rgb-leds
+parent: rgb-code
+ctime: 2012-03-10
+mtime: 2012-03-10
+
+# PWM drive
+
+The LEDs in the module receive varying current to adjust their brightness via
+the hardware PWM features of the PIC16LF1933 in conjunction with Timer 2. The
+module has 4 capture/compare peripherals, which is perfect for the 4 LEDs in the
+module.
+
+Each PWM output controls a simple current limited 2-transister drive circuit.
+This circuit is superior to a simple single transistor switch, as the CE
+junction of one transistor is used as a fixed voltage drop controlling current
+through a resistor of known size. This is particularly nice given that
+different LED modules have differnt voltage drops, and voltage drop is also a
+function of current and temperature. A fixed current driver removes these
+variables.
+
+# Mixing color and brightness
+
+An interesting challenge is to manipulate the output of the discrete color LEDs
+both for the purpose of emitting a specific color and for controlling the
+brightness. The solution is to treat the pre-computed PWM output value as a
+fraction of the maximum value (255). In the same fashion, the color range and
+the brightness are also treated as a fraction of their respective maximums.
+Therefore, the rgb drive output is essentially the product of the color and
+brightness values. Simple, and it seems to work out pretty well.
+
+ rgb = 255 * (color/color_max * bright/bright_max)
+
+Of course, for this processor the preference is to do this computation in
+integer math. The actual implementation looks more like this:
+
+ color: 0..63
+ bright: 0..BRIGHT_MAX
+ rgb = (color << 4) * bright / 4 / BRIGHT_MAX
+
+# LEDs
+
+An interesting effect was uncovered during testing. A certain delta change in
+drive string of a LED at a relatively low average power level is readily
+perceptible vsually, while the same delta is hard to detect at higher power
+levels. Some research shows this to be a nature of the human eye -- it
+perceives changes at lower intensities more readily than at higher percentages
+[(1)](http://neuroelec.com/2011/04/led-brightness-to-your-eye-gamma-correction-no/).
+To get a perceived linear output, the PWM value must be adjusted according to
+CIE Lightness.
+
+ L* = 116(Y/Yn)^1/3 - 16 , Y/Yn > 0.008856
+ L* = 903.3(Y/Yn), Y/Yn <= 0.008856
+
+Using these formulas, a look-up table can be created to provide the
+compensation. It works pretty well. The rgb.c and rgb.h files in the
+[repository](http://oss/gitweb?p=rgblamp.git;a=summary) implement this feature.
+Note that there are two different look-up tables available, depending upon the
+resolution desired.