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..
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:
- 1x Arduino Uno
- 1x breadboard 830 point
- 12x jumper wires
- 1x LED RGB 5mm (common anode)
- 3x 220 ohm resistors
- 3x pushbuttons 6x6mm
- 3x 10K ohm resistors
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.
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
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.
Sketch Code
For this tutorial I decided to split the sketch in 3 blocks of code:
- constants and globals
- initialization
- 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:
The video cannot be shown at the moment. Please try again later.
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.