Electronic – Regulate an RGB LED via PWM, both in brightness and in hue

atmegaatmega1284pavr

I am looking to regulate programmatically an RGB LED both in terms of brightness and in terms of hue. So far I have learned that I can use PWM to do this, but I am unsure as to what the details are. I am trying to integrate this into an AVR project using an ATMEGA1284.

Things I know:

  • I will need 3 PWM pins
  • PB3, PB4, and PB6 are PWM pins on my chip

Here is an LED that I think I can work with. Here is another. Does anyone know if my goal can be accomplished? Further, does anyone have experience with using PWM with the ATMEGA1284?

Best Answer

There are two things you need to understand

  1. The intensity of an LED can be controlled using PWM (pulse width modulation), which turns the LED on and off for some length of time.
  2. RGBs are comprised of three LEDs packaged together - red, green, and blue. The perceived color, or hue, is created by setting the intensity (brightness) of each of these internal LEDs.

LED Intensity (Brightness) using PWM

There are many different ways to do PWM, and your MCU datasheet will detail some of them in the timer/counter peripheral section if it can do hardware PWM; however, you can also "bit bang" PWM in software...

// pwm pseudo code
while (true) {
    set(pin)
    delay(PIN_ON_TIME)
    clear(pin)
    delay(PIN_OFF_TIME)
}

The percentage PWM period is the ON + OFF times, and the duty cycle is the percentage of ON / Period. A 50% duty cycle means the pin is on half of the time. However, this does NOT mean the LED is at half of its intensity. You have to refer to the LED datasheet to get that sort of information. What it all boils down to is the average current passed through the LED over time, and our perception of the dissipated light intensity. Different LEDs respond differently to the same amount of current.

Doing the above code is really bad though, since it wastes 99% of your CPU cycles. I often use the timers to do a quasi-bit-banged PWM on as many pins as I want, and have talked about doing this here, here, and here. There are also plenty of other answers on using PWM with AVR, so I leave that research to you.

LED Hue (Color) using PWM

If you can simultaneously drive each R, G, & B LED with a PWM algorithm (independently controlling the intensity of each LED), then you can use them to create every possible color.

The tool on this website allows you to play with different RGB intensities to create different colors. For example, to create the secondary colors, use:

 R   G   B
255 255  0  = Yellow
255  0  255 = Magenta
 0  255 255 = Cyan

where 255 is a 100% duty cycle (max of 8-bit value is 255).

Final Thoughts

  • To get perfect colors, you will have to manually fine tune the intensities of each LED, and/or adjust it's driven current with a resistor. I can gaurantee you that 100% RGB with matched currents will not give you a clean white.
  • RGB values are often encoded into a single 8, 16, etc bit value, depending on how many unique colors you want to have, and how the range of any of the individual R, G, or B values effect those colors.
  • If you are using a specific color pallet, it's recommended to create a lookup table with arrays that will return the correct RGB values for whatever color you want to produce.
  • The comments on your post cover the issue of which LEDs to use, so I defer to them.