RGB LED Control

Explanation:

This program demonstrates how to drive an RGB LED to create 4096 different colors. Each of the three elements (red, green and blue) responds to 16 different levels. A value of 0 means the element never turns on, while a value of 15 means the element never shuts off. Values in between these two extremes vary the pulse width.

This program is an interrupt driven three channel PWM implementation.

The basic carrier frequency depends upon the microcontroller clock speed. For example, with an 8 MHz clock, the LED elements are modulated at about 260 Hz. The interrupts are generated by Timer 0. With an 8 MHz clock they occur about every 256 uS. The interrupt routine consumes about 20 uS.

Do not forget the current limiting resistors to the LED elements. A value of around 470 ohms is typical, but you may want to adjust the individual values, to balance the color response.

In this demonstration, three potentiometers are used to set the color levels using the slalom technique.

Demonstration program:

    ;----- Configuration
    #chip 16F88, 8                ;PIC16F88 running at 8 MHz
    #config mclr=off              ;reset handled internally

    ;----- Constants
    #define LED_R PortB.0         ;pin to red element
    #define LED_G PortB.1         ;pin to green element
    #define LED_B PortB.2         ;pin to blue element
    ;----- Variables
    dim redValue, greenValue, blueValue, ticks as byte
    ;----- Program
    dir PortA in                  ;three pots for inputs
    dir PortB out                 ;the LED outputs
    on interrupt Timer0Overflow call update
    initTimer0 Osc, PS0_1/2
    do
      redValue = readAD(AN0)/16   ;red -- 0 to 15
      greenValue = readAD(AN1)/16 ;green -- 0 to 15
      blueValue = readAD(AN2)/16  ;blue -- 0 to 15
    loop

    Sub update                    ;interrupt routine
      ticks++                     ;increment master timekeeper
      if ticks = 15 then          ;start of the count
        ticks = 0
        if redValue <> 0 then     ;only turn on if nonzero
          set LED_R on
        end if
        if greenValue <> 0 then
          set LED_G on
        end if
        if blueValue <> 0 then
          set LED_B on
        end if
      end if
      if ticks = redValue then    ;time to turn off red?
        set LED_R off
      end if
      if ticks = greenValue then  ;time to turn off green?
        set LED_G off
      end if
      if ticks = blueValue then   ;time to turn off blue?
        set LED_B off
      end if
    end sub