PIC16F628 4 RGB LED PWM Controller

January 6, 2009

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:

  1. January 6, 2009 at 5:57 PM | #1

    That’s cool and I guess almost everyone is fascinated by LED’s, I can even remember my first projects, they we’re all based on LED’s :)

  2. David
    January 9, 2009 at 6:05 PM | #2

    man you’re the boss
    your work is truly amazing
    and the LEDs ooooooh!!!!! the LEDs are beautiful.
    your work really inspired me
    Thanks for sharing

  3. Eric Flynn
    January 18, 2009 at 7:33 PM | #3

    Shouldnt disabling MCLR eliminate the need for the RA5 pullup!!!

  4. Ale914
    March 13, 2009 at 8:43 AM | #4

    Hey, good work.
    Give a look at mine, very similar work, http://www.agilesystems.it/?p=56

    Alessandro

  5. July 5, 2009 at 9:43 AM | #5

    why the 4 elcos? i see only one on the pcb?

    and how far from each other can you connect the PCB and that it stil works?

    and on al other side i read that you always need a kristal if you use rs232? but this works good?

  6. santiago acha
    July 28, 2009 at 8:32 AM | #6

    WOW!!!

    what Eric Flynn Says is correct, you can use NOMCLR instead of MCLR and remove the resistor, but declare that pin as an output.

    the resistors that you are using, what values they have?

    you are using a pwm working at 61,03515625 hz, timer0 overflow at 256us, but using 18 bits color (64 it’s the maximum in the pwmcount), so you can’t use values higher than 64 (0×40), right? have you try it to make it work with higher values on pwmcount?

    very interesting project anyway!!!
    congrats

    pd: my english is not perfect, i speak spanish ;)

  7. craig
    August 13, 2009 at 4:21 PM | #7

    I am trying to do a project for myself where I can control three channels of led lights (red/green/blue) via RS232 serial control from my PC. There will be at least three of each colour led, probably each led will need 3v/18mA but each colour channel could be wired in series.

    I need to control the brightness of each colour channel and control on /off flashes of each colour via rs232 (but do not need to control each led individually at this time)

    Ideally I would also like to power it via 9v battery as well as giving a choice for a mains power adaptor

    Any idea whether this project will do this as not sure about controlling the individual led colour brightness? Would be interested to know whether the pic program can be altered to suit if not

    Thanks for your help

    Craig

  8. craig
    August 13, 2009 at 4:22 PM | #8

    The led colour brightness would quite a few levels of intensity, say 50-100 if possible

  9. Leopold
    August 14, 2009 at 8:17 PM | #9

    Hi! I’ve tried to make a very similar project but I couldn’t succeed using internal RC with serial communication. It allways generated framing error. What do you think I might be missing?

    Thanks!

    Leo

  10. August 24, 2009 at 9:40 PM | #10

    Hi! Great project and thanks for sharing it!
    I’m trying it out but I don’t know what fuses/config word to use, could you tell me? And is there a way to test if it is working?
    I have tried your program and changed com3 to com1 but It didn’t work, I’ll check the circuit again meanwhile :)

  11. August 26, 2009 at 8:22 PM | #11

    Ok, got it all working :) com1 and theadress was set to zero.
    Time to learn how to send data to it! This is fun. Thanks!

  12. August 27, 2009 at 10:54 PM | #12

    This is some great eye candy! Have you considered combining your multicolored jewel with some of these low-cost RF receivers?: http://www.futurlec.com/Radio.shtml $6 for a receiver or $7 for a transceiver. I’m going to have to peak at your code and see how the timing works out for 12 pwm channels on a single chip! Nice work!

  13. September 18, 2009 at 4:21 PM | #13

    I have build it too, and it works…. I give them a adress with a terminal porgram….

    but if i let the visual basic program run for a long time… after a while one by one they stop with working…. … is see the rs232 still sending data too the PCB, but the don’t respons anymore….

    do somebody know why? a bug in the program?

    the only to start them again, is stop the movie, turn of the power for al the pcbs,and turn the power back on, start the movie again…. and than it works for a hour…or something

    Help somebody…

  14. October 21, 2009 at 2:15 PM | #14

    for the record, i was thinking about Connection Cloud today and was wishing that it was still up somewhere, and that led to wondering if maybe it was in a different form which led to a search which then led to finding your blog. I’m sad that cc isn’t still up, but that’s life, and at least it let me discover the stuff that you’re doing now with the LEDs and such which is awesome. A while back i did a collaborative project with a friend that knows much more about microcontrollers than i do build the hardware/circuit board to interface with a program called Max/MSP which allowed for infrared sensors to control music and video &c, and it’s always good to see projects like that crop up in other places and in unique ways. keep up the good work.

  15. B.N
    January 23, 2010 at 11:24 PM | #15

    Hello, I’ve been looking on the net and I have a somewhat self-ish question.
    I saw the pic of the printed board layout, are you allowing people to have the circuit design you created copied for personal use?
    Also, have you considered expanding the circuit to do something like PC control via usb?
    (Just curious)

  16. March 22, 2010 at 4:07 PM | #16

    Your demo program? is that using commando 1? or 8?

  17. behzadabf
    May 31, 2010 at 8:08 AM | #17

    wow , good for you. i’m just started to learn 89c51 micro controller and when i see this ,i say to myself you can’t Never done .

  18. Chris F
    June 17, 2010 at 4:36 AM | #18

    I am working with a friend to write a driver interface for our Christmas Lighting program called Vixen to run these. However, I do not see a whole lot on how to set them up. Especially getting the address set and how to send the different commands.

    Can I get some more details on that please?

  19. Phil
    June 30, 2010 at 10:54 PM | #19

    RA5 is not the same as MCLR on those parts. RA5 is a regular I/O pin, except that the output driver is open-drain. I was bitten by the same RA5 problem with the 16F627A a few years back.

  20. mehmet
    November 13, 2010 at 7:06 PM | #20

    Hi ,We can use this project to video screen or RGB display.Thanks

  1. July 13, 2009 at 12:32 PM | #1
  2. July 13, 2009 at 1:01 PM | #2
  3. July 13, 2009 at 5:52 PM | #3
  4. July 13, 2009 at 11:33 PM | #4
  5. July 16, 2009 at 2:08 PM | #5
  6. July 19, 2009 at 10:39 PM | #6
  7. February 16, 2010 at 12:44 PM | #7
  8. June 28, 2010 at 9:21 PM | #8

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>