PIC RGB is a circuit that generates random RGB colors using a RGB LED and fades between them. The idea for this circuit came from the candle simulator  and another project called TinyRGB  .
The challenge was to create an algorithm that could fade 3 independent colors at different speeds in the same time interval, using integer math, (of course).
Basic schematic includes a voltage regulator 78L05, the PIC with a decoupling capacitor and a few resistors.
Vred = 2.1V, Vgreen=3.4 and Vblue=3.5V
Rred = 145 Ohm -> 150 Ohm
Rgreen = 80 Ohm -> 82 Ohm
Rblue = 75 Ohm -> 82 Ohm
The push-button switches between running modes, random and sequence.
Note: PIC pin1 is the lower right one.
The software is written in C and consists on a random number generator, an intensity fading function and a triple PWM modulator. The triple PWM modulator uses just one timer for all the output signals. All three color components have 256 levels of intensity and there are two working modes: random and sequence.
The random number generator is the same from the candle simulator, except that it now returns a char. The previous version returns a single random bit.
The fading function has undergone three evolutions along the process of development, each being an improvement of the previous one.
Version 3 example:
Current color RGB=(10, 200, 50) needs to fade to Final color RGB=(10, 150, 30) in 2 seconds (40 cycles). The formulas are:
|Current RGB||Final RGB||Step||Error||Error Period (looks more like a frequency)|
What does it mean? It means that Red will not be incremented in 40 cycles at all. It means that Green is going to be decremented 1 in each cycle, because of the step, and an extra 1 every 4 cycles, because of the error. And finally Blue will be decremented every 2 cycles one unit because of the error!
Finally the PWM modulator controls the brightness of the LEDs. There are several ways of creating the PWM signal, this time only one timer was used. To be able to display 256 levels for each color component from 50Hz to 100Hz, the timer must run from 50*256 interrupts per second to 100*256 interrupts per second. There's a counter variable associated with the timer which is incremented every time the timer generates an interrupt. Every time the counter variable overflows from 255 to 0, all 3 components (R,G,B) are turned on. In the following cycles the color components will be turned off when their values match the value of the counter.
The sequence mode differs from the random mode because the colors emitted by the LED are pre-programmed. The sequence is Green, Green/Blue, Blue, Blue/Red, Red, Red/Green and starts over.
To switch between the random mode and the sequence mode press the button connected to GPIO1 (pin 6).
After testing and comparing the three versions this is what I was able to conclude:
Compiling and running with the PWM at 100Hz you'll need to turn on code optimizations in HI-Tech picc otherwise there is not enough time to complete the ISR before another interrupts occurs. This is because the timer generates 100*256 interrupts per second and the PIC is being clocked from the internal 4Mhz oscillator. The time between interrupts is 39us and running at 4Mhz the PIC is able to execute an instruction every 4*1/Fosc = 1us. So it is possible to execute, at most, 39 instructions inside the interrupt service routine.
The resistor values are not critical. In fact you may choose values above or below the theoretical ones that make the light more pleasant to you. I'm using 200 Ohm for Red, 150 Ohm for green and 100 Ohm for blue and the amount of light coming out of the LED is huge and somewhat blueish!
Note: I'm using a common anode rgb LED in which whenever I want to enable one LED, I have to drive its corresponding PIC pin to 0 and vice-versa. If you want to use a common cathode LED, just change the ON and OFF macros in the C file and recompile. It should be enough.