Controlling an RGB LED with Arduino

In this simple project I’m going to show you how to control an RGB LED (common anode) using an Arduino Uno and few push-buttons.

Description

In this project I’m going to control an 5mm RGB LED using three pushbuttons and an Arduino Uno.

Every pushbutton is controlling a colour channel of the LED, i.e: the first button is controlling the Red channel, the second button is controlling the Green channel and the third button is controlling the Blue channel.

Pushing a single button will increase gradually the brightness of the corresponding colour channel until it will reach its maximum brightness, which basically means you get a Red, a Green or a Blue light. Pushing more buttons at the same time allows you to get even more colours. For example pushing the first and the second buttons makes yellow, pushing the first and the third buttons makes fuchsia, etc..

RGB LED - multiple colors

Obviously this is just a simple project aimed to show you how to control an RGB LED, but it should be quite easy to extend it and to use it as a starting point for more interesting experiments with RGB LEDs. For example a simple and quick modification could be using 6 pushbuttons to have full control on the brightness value of each colour component (3 pushbuttons to increase the brightness of the 3 colours and 3 pushbuttons to decrease it).

Components

This is what I used for this project:

Obviously you can find all these components bundled in one of the LEDs kits available in our online shop.

RGB LED

An RGB LED is an LED which actually contains 3 LEDs: one Red, one Green and one Blue. By controlling the brightness of each of the three LEDs you can get pretty much any colour you want.

5mm RGB LED common anode

According to the type of RGB LED, the 3 LEDs can share the anode or the cathode, which is the longest pin coming out from the LED’s head. How you may guess, the other three pins are used to control the three colours.

The way you control and wire an RGB LED is different if you’re using a common anode or a common cathode LED: when using a common anode LED you need connect the long pin to 5V and write 0 to any of the three LEDs pin to turn it on, whereas when using a common cathode LED you need to connect the long pin to ground and write 255 to any of the three LEDs pin to turn it on.

Wiring

Controlling an RGB LED with Arduino - breadboard and wiring

This project is using a common anode RGB LED, so the longest pin of the LED is connected to 5V, whereas the three other pins are connected to three Arduino pins via three 220 ohm resistors. The first pin (left of the longest one) is controlling the Red LED, the third pin is controlling the Green LED and the last one is controlling the blue LED.

Pushbuttons require a normal wiring with one side connected to 5V, the other side connected to ground with a 10K ohm resistor and an arduino pin connected to the line where the button is connected to ground.

RGB LED and Arduino Uno: wiring scheme

Sketch Code

For this tutorial I decided to split the sketch in 3 blocks of code:

  1. constants and globals
  2. initialization
  3. main loop

That’s just for clarity, so if you want to use this code in your project you’ll need to copy and paste the three blocks in a single file or you can download it from our website.

Before starting with the code I should probably remind you that this project is based on a common anode RGB LED so to turn a single component fully on we need to write 0 to the corresponding Aruino pin, whereas to turn it fully off we need to write 255. These values are inverted when using a common cathode LED so the whole logic of this sketch should be inverted if using a different type of LED.

In the first block there’s all the code used to declare and initialize global and constant data.

const byte NUM_COLORS = 3;

// REQUIRED INTERVAL (IN MS) BETWEEN ANY CHANGE TO A COLOR CHANNEL
const byte COL_INTERVAL  = 50;
// VALUE ADDED OR SUBTRACTED TO A COLOR CHANNEL WHEN CHANGING ITS VALUE
const byte COL_VAR       = 5;

const byte DELAY_TIME    = 17;  // ~60FPS

const byte PIN_COLORS[] =  { 3, 5, 6 };    // OUTPUT PINS 
const byte PIN_BUTTNS[] =  { 9, 10, 11 };  // INPUT PINS

// COLOR OF EACH CHANNEL
byte VAL_COLORS[]   = { 255, 255, 255 };
// TIMER USED TO CHANGE A COLOR QUITE SLOWLY
byte TIMER_COLORS[] = { 0, 0, 0 };

Comments and names used for variables and constants should be enough to understand what’s going on here. Probably the only thing to point out is that I’m using two arrays (instead of 6 constants) for the values of the input and output pins. This will allow to save repeated code using a for cycle to get the values from the buttons and to write the values to the LEDs.

The setup function is pretty simple, all it does is initializing the pins and writing 255 to the three LEDs to turn them off.

void setup() 
{
  // cycle through the 3 channels  
  for(int i = 0; i < NUM_COLORS; i++)
  {
    pinMode(PIN_COLORS[i], OUTPUT);    
    pinMode(PIN_BUTTNS[i], INPUT);

    analogWrite(PIN_COLORS[i], 255);
  }
}

Finally the main loop which is the core of the sketch.

A for loop cycles through the three buttons to get their values and, according to that, to determine the value of the corresponding colour component.

While a button is pushed (value is HIGH)  the brightness of corresponding colour is increased up to its maximum value, whereas the brightness of a colour is decreased until it’s off when a button is not pushed (value is LOW).

The brightness of the 3 colours is changed gradually using 3 timers which basically add a delay of COL_INTERVAL ms to every change in the values, creating a smooth transition between the OFF and ON state and back.

void loop() 
{   
  // cycle through the 3 buttons/channels
  for(int i = 0; i < NUM_COLORS; i++)
  {
    byte button = digitalRead(PIN_BUTTNS[i]);  

    if(HIGH == button)
    { 
      if(VAL_COLORS[i] > 0)
      {
        TIMER_COLORS[i] += DELAY_TIME;

        if(TIMER_COLORS[i] > COL_INTERVAL)
        {
          VAL_COLORS[i] -= COL_VAR;

          TIMER_COLORS[i] = 0;
        }
      }
    }
    else  // button is LOW, not pushed
    {
      if(VAL_COLORS[i] < 255)
      {
        TIMER_COLORS[i] += DELAY_TIME;

        if(TIMER_COLORS[i] > COL_INTERVAL)
        {
          VAL_COLORS[i] += COL_VAR;

          TIMER_COLORS[i] = 0;
        }
      }
    }

    // write color for LED i
    analogWrite(PIN_COLORS[i], VAL_COLORS[i]);
  }

  // pause for a short time
  delay(DELAY_TIME);
}

The last instruction of the loop is a delay which keeps the logic running at about 60FPS (Frames Per Second) and allows to not care about de-bouncing the values read from the buttons.

Project in action

Finally a short video to show you the project in action:


Download YouTube Video | Convert YouTube to MP3 | Replay Media Catcher

I hope you enjoyed this simple project and that everything was clear, but if you have any question don’t hesitate to leave a comment and I’ll be happy to answer.

2 thoughts on “Controlling an RGB LED with Arduino

  1. Niceness, thanks for the tips, i’ve been wanting to try that out with an arduino for a while, great example, although it would help if you added another picture of the circuit switched around 180 degrees, since you can’t quite see where the 10k resistors go, and same with some of the wires. The rest is well done. Thanks again.

Leave a Reply

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


9 + = 12

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>