Practical PIC Projects

 

 

RGB LED PWM Driver
Standalone PWM
controller for  RGB LEDs
using 12F6xx PIC

  • Description

  • Operation

  • Download code

  • Construction & PCB

  • Design Ideas

  • Sequence Data file format

  • Updates

  • FAQ

 


 


Want to build an RGB LED controller that you can program with your own custom sequences and effects? Then read on. 

The RGB LED controller has proved to be very popular project and has been the most frequently downloaded code on the site since it was made available.  I've been contacted by people who have incorporated this project into all kinds of things including mood lamps, lighting for a sculpture, accent lighting for rooms and an illuminated prize trophy.

For 2006 I  completely rewrote the application making it much easier to add, edit and change the sequence data.  I also added a sleep function so a battery operated version can be built that doesn't need a power switch. 

For 2008 I've released version 3 of the code which now allows you to stop the running sequence at any point so you can 'freeze' a colour.

All code runs on the 12F629, 12F675 and the newer 12F683 which, with 2K of program memory has plenty of room for user sequences.


Description

The original RGB PWM driver application that I wrote in 2004 had a few shortcomings. Probably the biggest was that it was not easy to add to or change the sequences.  This new version addresses that problem, is more flexible and now includes the ability to put the PIC to 'sleep' and 'wake' it again using the sequence select switch, eliminating the need for an on/off switch in battery powered applications.

The circuit uses (RGB) Red, Green and Blue high brightness LEDs that are pulse width modulated (PWM) to vary the intensity of each colour LED.  This allows effectively any colour to be generated with rapid changing strobe effects, fast and slow colour fades as well as static colours.   The data used to set and change the colours is held in an easy to edit file so if you don't like the sequences provided with it, you can modify the sequence data include file yourself and reprogram with your own sequences.

The code can be assembled for use with the following PICs: 12F629, 12F675, 12F683.  Just select the correct processor in the MPLAB IDE before assembling.


Operation

  • When the PIC is first powered on after programming, it should start running the first RGB sequence found. If you're using the original sequences supplied with the code here it will run a sequence of red-fade out, green-fade out, blue-fade out repeatedly.
     
  • Press the SW1 sequence select switch to step through all available sequences. When the last sequence has been reached it will go back to the first available sequence.  Each time the SW1 switch is pressed the RGB LED PWM values are set back to 0 (LEDs off)
     
  • Press and hold SW1 switch for about 1.2 seconds to put the PIC into sleep mode.  Once in sleep mode, press the SW1 switch for about 2 seconds then release it to wake the PIC from sleep. If the SW1 button isn't held for two seconds the PIC returns to sleep - this prevents the circuit from being accidentally turned on.  When  operating the RGB controller from batteries (without a 78L05 regulator) a power on/off switch is no longer needed since the PIC uses only a few microamps when 'sleeping' 
     
  • About 10 seconds after the SW1 sequence switch is last pressed the currently selected sequence number is saved to non-volatile EEPROM memory.  When the RGB LED driver is next powered on, the saved sequence number is read back and will automatically start running.
     
  • Anytime the PIC is put into sleep mode by holding SW1 switch down, the currently selected sequence is also saved to EEPROM.

Code Download

There are two versions of firmware available for this project.  Version 3 adds a run/hold function that allows the sequence and colour to be 'frozen' but is otherwise the same as Version 2.  Both versions can be downloaded here and version 2 will remain available indefinitely.

  • Version 2 firmware
    Download source code  rgbsa-inet.zip (V:2.0.2 09/06/2007)

    The source code comprises a single .ASM file and four .INC files.  All five files are required and should be extracted to a single directory on your computer.  To reassemble the code, open the rgbsa-inet.asm file, then select Project - Quick Build from the MPLAB IDE menu bar.
     

  • Version 2 Programmer ready .HEX files
    Download Hex for 12F629 and 12F675 (right-click Save As)
    Download Hex for 12F683 (right-click Save As)
    (please read the FAQ below)
     

  • Version 3 firmware
    Description and source code
    download here (V:3.0.2 09/06/2008)


Construction & PCB


PCB100B

 

 

 

Modified PCB with ICSP header for development work

 

 

Frosting spray, turn clear LEDs into diffused LEDs

Schematics and PCB artwork

Construction tip:

When you solder the LED's to the PCB, only solder one lead of each LED.  Once all the LED's are fitted, you can move the LEDs around to get them all neatly aligned.  Once you have them aligned, solder the remaining lead on each LED.  If you try moving them once both leads are soldered you risk ripping the copper off the PCB.

Where to get parts

I don't sell complete kits of parts for this project but you can buy all the components from Rapid Electronics; to that end I have put together a full component list here

Not sure what series resistors you need?

try the LED Resistor calculator

Turn water clear LEDs into diffused LEDs the easy way.

Almost all high brightness 5mm LEDs come in a clear plastic package, but for many applications what you really want is a diffused LED.   Plasti-kote's glass frosting spray is a quick and easy way to make clear LEDs diffused. 

I've used the frosting spray on LEDs with this project and it really improves the colour mixing effect. 


 


Driving large arrays of LEDs

If you want to drive large arrays of LEDs using the PIC you need to use a logic level power MOSFET.  The  circuit shown below is a generic driver that will work for most applications.  Depending on the input voltage and the forward voltage of the LEDs used, you may be able to increase the number of LEDs in each column.  You could also use this type of circuit to control higher wattage LEDs, but remember the power rating of the LED current limiting resistor needs to be taken in to account.  (power dissipated in the resistor is = I2R  )

PDF version

Design Ideas

Piranha LED colour bar

Here's a one off light bar I built using 20 Piranha RGB LEDs and a custom MOSFET driver board.  Assembled into a 25mm x 50mm x 1000mm aluminium 'U' section.  This was fitted under a wall shelf to illuminate the floor.  It's very bright and gives a nice even illumination without any additional diffuser.  Again this uses the code available to download on this page

 

I used 0805 SMD resistors, 68R for the Red and 47R for the Green and Blue LEDs. Running from a 5 volt supply it draws about 1.7 amps max.


 

  • A battery operated mini RGB mood lamp using Piranha RGB LED.

    Housed in a four AA battery holder, modified to use three batteries with the PIC and RGB LED controller PCB located in the space where the fourth battery would normally fit.

    (Battery box from Rapid Electronics, part # 18-2905)

    When the mode button is held for over 1.5seconds the PIC goes to sleep. When the PIC is sleeping pressing and holding the mode button for 1.5 seconds will wake the it again so there is no need for an on/off switch.

    After I saw these illuminated awards pictured below I couldn't help but have a go at making one myself.  These were based on my  code here on this page.   More photo's of this can be found here

 


Format of the Sequence Data

The data used by the application for the RGB sequences is held in the file 'sequenceData.inc'  You can edit this file to add, remove or change the data provided.  You must ensure that it follows the format described.  In particular pay attention to the 'end of sequence' and 'end of all data' markers and also ensure that each line of sequence data contains five comma separated entries. (see screen dump below)

In the screen dump above note the 'end_of_sequence' markers circled in red and the 'end_of_all_data' marker circled in purple.

You must have at least one sequence present up to a maximum of 256 individual sequences, although you're likely to run out of available memory on the PIC before you reach this limit.

  1. Each line of data starts with a 'dt' (data table) assembler directive.

  2. All data is specified using decimal values.

  3. Each data value must be separated by a comma

  4. The sequence data on each line has five fields:

    1. Fade Rate: speed the colours fade from the current values to the new values. Each step occurs at an interval of 5ms x Fade Rate.

      • Fade Rate value of 0 indicates the RGB values will be updated immediately without fading.

      • Fade Rate value must not be set to 255 except to indicate end of sequence. (see d. below)
         

    2. Hold Time: after fade completes, delay before moving to next line of data. Interval is 50mS x Hold Time

      • Hold Time value of 255 following a Fade Rate of 255 indicates end_of_all_sequence data.
         

    3. Red, Green and Blue PWM values. 0 = 0% (LED off) through to  255 = 100% (LED fully on)

      Typically changes in LED brightness are more noticeable between 0 and 128 than from 128 to 255.
       

  5. End of the current sequence data is indicated by the Fade Rate field being set to '255'.  When the application encounters this it restarts the sequence from the beginning.

  6. At the end of all available sequence data both the Fade Rate and Hold Time fields must be set to '255'

After editing sequenceData.inc the file should be saved and the rgbsa-inet.asm reassembled. The resulting rgbsa-inet.hex file can them be programmed into the PIC.


Updates

March 2007

I've recently bought some Piranha RGB LEDs from Rapid Electronics (p/n 72-8998) .  This device contains three LED dies in a clear 4 pin package with 5mm lens.  The LEDs are closely mounted and produce good colour mixing when viewed straight on,  If for the red LED is 50mA while the blue and green If is 30mA, however, even driving it directly from a PIC at ~25mA brightness is very good. 

At 20mA outputs are: Red - 3,000mcd, Green - 4,200mcd, Blue - 2,180mcd.  While this might not sound very bright compared to 10,000mcd and better 5mm LEDs it actually compares very well; it's much brighter than the figures suggest. With all three colours in a single package it performs much better than discrete 5mm LEDs, especially where good colour mixing is concerned.

Although my PCB layout can't accommodate this LED directly, my code will drive the LED quite happily. You'll need to connect GP4 on the  PIC to Vss so the outputs are active low.  Currently (March 2007) the price is only £0.66 for one-off quantities which compares well with buying discrete red, green and blue 5mm LEDs.

 

April 2007

I've been working on a constant current source for 350mA Luxeon type LEDs that can be used with RGB LED PWM controller on this page and the simple serial controller also on this web site.

For details see here

 

October 2007

For a serial controlled addressable RGB LED PWM controller, supporting up to 128 drivers with indivual addresses

 see details here


Saving the Internal Oscillator calibration instruction.

For details on the internal oscillator calibration word, download the Microchip datasheet for the 12F629 / 675 and read section 9.2 and in particular sub-section 9.2.5.1

This only applies to the 12F629 & 12F675.  The 12F683 uses a different method for calibration

See my tip to make sure you will never lose the OSCCAL setting

If you have erased the OSCCAL setting, use this circuit and code to recover it
 


FAQ:

  • Multiple RGB lights not staying in sync
    This note follows a query I had from someone who built these RGB lights.  Because the timing is generated from the internal 4Mhz oscillator and there is no way to synchronize each device with others, even if they are running the same sequence, the colours quickly get out of sync with each other. 

    If you're building a light bar or any application where you need more than one unit and they need to stay in sync you should build the 'serial controlled RGB driver'.
     

  • Oscillator Calibration Instruction
    I've had a number of enquiries from people who can't get the code to work and it has transpired that they / their programmer has erased the OSCCAL value. Without the calibration RETLW instruction the code crashes so you must ensure that it is present or the code will not run. 

  • How can I recalibrate the internal oscillator on a 12F629 or 12F675?

    I've written an application that will enable you to recalibrate a 12F6xx PIC
    See details and download code here

    Alternatively just insert a RETLW 0x80 instruction at address 0x3FF.  This won't calibrate the oscillator correctly but the code will now run.

    See my tip to make sure you will never loose the OSCCAL setting

    I also understand that Microchip's PICkit2 Development Programmer/Debugger has a feature that will calculate and replace a missing OSCCAL value.
     

  • Verify Errors after programming
    The RGB light programme code uses the PICs EEPROM to store the last used mode.  When the PIC is powered up for the first time after it has been programmed it checks to see if the last sequence value saved in EEPROM is less than or equal to the number of available sequences. If it is not, the code set the value in the EEPROM to 0.

    I had a series of e-mails from a guy in Greece who had lots of problems with "Verify 0000!" errors.  I eventually built the programmer hardware he was using and ran the software to try and find out what was happening.  It turned out that this particular combination of programmer/software was powering up the PIC between writing the code into the PIC and verifying it.  This caused the EEPROM to get initialised to "00" but the software was still expecting "FF" so the verify failed.

    The programmer hardware was PLMS OziPIC'er  and the software was IC-Prog 1.05D.  I must stress that apart from this idiosyncrasy this is a perfectly capable PIC programming setup and once aware of what is happening it is easy to account for and work around. 

    (A special thank you to Panagiotis from Athens - thanks to the Internet, his excellent English and much patience we got to the bottom of this problem despite the language barrier and the distance)

  • Editing, adding changing the RGB sequence data.

    All the sequence data is now held in the sequenceData.inc file so it is really easy to add your own sequences.  The application works out how many sequences are present, where they start and finish and takes care of page boundary crossing. All you have to do is put the correctly formatted data into the file, save it then reassemble.

    Please take your time when editing the sequenceData.inc file since errors are likely to cause the RGB Driver to do unexpected things or crash.

    If you see an 'Warning [220]' error during assembly like that shown below, you've added more sequence data than the PIC has available memory.


    Clean: Deleting intermediary and output files.
    Clean: Done.
    Executing: "C:\Program Files\Microchip\MPASM Suite\MPAsmWin.exe" /q /p12F675 "rgbsa-inet.asm" /l"rgbsa-inet.lst" /e"rgbsa-inet.err"
    Warning[220] C:\CODE\RGBSA-INET.ASM 158 : Address exceeds maximum range for this processor.


    If you see an Error [112] message during assembly check for missing comma separators in the sequenceData.inc file

    Clean: Deleting intermediary and output files.
    Clean: Done.
    Executing: "C:\Program Files\Microchip\MPASM Suite\MPAsmWin.exe" /q /p12F675 "rgbsa-inet.asm" /l"rgbsa-inet.lst" /e"rgbsa-inet.err"
    Error[112] C:\CODE\SEQUENCEDATA.INC 56 : Missing operator

  • Comments or problems with this code / project? Please send an e-mail to: