PIC16F628 4 RGB LED PWM Controller

I am a big fan of LEDs.  Bright, colorful, flashing LEDs.  So, given my affinity for LEDs, I decided to work on a controller that me and a few of my friends could use as an art project/passive information display.  I have posted videos from the first prototypes (here and here), but it has been tough to dedicate time to further development given my research, so I thought I would post the information so that anyone can take the design and modify it to their liking!

Some insipration came from the BlinkM “smart LED” and the ShiftBrite RGB LED Module, but I was interested in using RS232 serial control.  Therefore, I chose one of my favorite simple-to-use microcontrollers, the PIC16F628.  The advantages include the built-in 4MHz oscillator, hardware USART, and ease of reprogramming.  A couple of features I had in mind during the design:

  1. Multiple intensities for each color (using PWM)
  2. Multiple individually controllable RGB LEDs
  3. High-speed update rate
  4. Daisy-chainable and addressable
  5. Simple serial control

Schematic
Here
is the full schematic for the driver. I chose to use a PIC16F628 as the microcontroller because it is cheap, has a internal oscillator (4 MHz) and an internal USART. NOTE: There is an error in this schematic and a pull-up resistor on RA5 (pin 4 in the schematic) is necessary.  See the bottom of the post for an updated schematic and board.

Board
I decided I would try getting a PCB printed for the first time, so I got boards created at BatchPCB.com for $5 each.  The total for 4 boards shipped was $32.36 (4 x $5 for the boards and $12.36 for shipping and handling).  They took a long time to arrive, but the quality was well worth the wait.  NOTE: There is an error on the first revision of the board and a pull-up resistor on RA5 (pin 4 in the schematic above) is necessary.  You can see how I compensated for the mistake in the second picture below (look on the back of the upper-left board).  This will be corrected in future revisions.  See the bottom of the post for an updated schematic and board.

Control Format
The current firmware has 8 commands (the 9th, self-test was removed to save space).  See the source code for the firmware for how the commands are implemented, but here is some example usage:

  • Turn off all LEDs: 0h2000FF
  • Make all LEDs full-intensity red: 0h2F00FF
  • Make all LEDs full-intensity red: 0h1F00F00F00F00FF
  • Make all LEDs at address 1 half-intensity green: 0h207001
  • Make LED 2 at address 1 half-intensity green: 0h100007000000001
  • Load start-up settings for all controllers: 0h40FF

Commands:

  1. Update individual LEDs using 4-bit exponential update
    Byte 1, Nibble 1 = led1Red;   Byte 1, Nibble 2 = led1Green
    Byte 2, Nibble 1 = led1Blue;  Byte 2, Nibble 2 = led2Red
    Byte 3, Nibble 1 = led2Green; Byte 3, Nibble 2 = led2Blue
    Byte 4, Nibble 1 = led3Red;   Byte 4, Nibble 2 = led3Green
    Byte 5, Nibble 1 = led3Blue;  Byte 5, Nibble 2 = led4Red
    Byte 6, Nibble 1 = led4Green; Byte 6, Nibble 2 = led4Blue
    Byte 7 = theAddress
  2. Update all LEDs using 4-bit exponential update
    Byte 0, Nibble 2 = led1Red = led2Red = led3Red = led4Red
    Byte 1, Nibble 1 = led1Green = led2Green = led3Green = led4Green
    Byte 1, Nibble 2 = led1Blue = led2Blue = led3Blue = led4Blue
    Byte 2 = theAddress
  3. Save start-up settings
    Byte 1 = theAddress
  4. Load start-up settings
    Byte 1 = theAddress
  5. Get address
    Byte 1 = theAddress
  6. Set address (one-time set)
    Byte 1 = theAddress to save
    Byte 2 = theAddress
  7. Disabled in this release.
    Self test
    Byte 1 = theAddress
  8. Update individual LEDs using 6-bit update
    Byte 1 = led1Red;    Byte 2 = led1Green
    Byte 3 = led1Blue;   Byte 4 = led2Red
    Byte 5 = led2Green;  Byte 6 = led2Blue
    Byte 7 = led3Red;    Byte 8 = led3Green
    Byte 9 = led3Blue;   Byte 10 = led4Red
    Byte 11 = led4Green; Byte 12 = led4Blue
    Byte 13 = theAddress
  9. Update all LEDs using 6-bit update
    Byte 1 = led1Red = led2Red = led3Red = led4Red
    Byte 2 = led1Green = led2Green = led3Green = led4Green
    Byte 3 = led1Blue = led2Blue = led3Blue = led4Blue
    Byte 4 = theAddress

Source Code
The PIC16F628 needs to be programmed with the firmware below.  The Windows application is included as an example of how one could control a 2×2 array of the PIC16F628 4 RGB LED PWM Controller boards (4×4 LEDs).

The first couple of prototypes have worked well, but I am still working on refining the PCB, circuit, firmware, and software design.  Here are a few pictures of the boards:

Update (01/06/2008)
Here is an updated schematic and board with the corrected MCLR pullup: