Fading RGB LED Arduino: Discover the components of an RGB LED, how to connect an individual or Keys RGB LED. You can Find Out how Easily fade an RGB LED in and out, to make a 'Breathing' LED, while at the same time keeping the same color profile during the fading.

Fading RGB LED Arduino:
  • Find out how to make a 'Breathing' RGB LED using any colour.

  • How to keep the same colour profile during 'Breathing'.

  • Find out the simple technique to make 'Breathing' work.
 There are two types of RGB led:
  • A serial RGB LED that has a built in communicator chip inside.
  • An original RGB LED with 3 diodes packaged inside - and nothing else.

Here we are talking about the original RGB LED.

The first thing to know about an RGB led is that it is simply composed of three light emitting diodes all enclosed in  the same package; Namely Red, Green and Blue LEDs.

The second thing to know is that you can get diffused or clear LEDs. You will want a Clear RGB led if you are going to install it behind a diffusing filter e.g. thin white or semi transparent plastic. This allows the maximum light intensity to get to the plastic screen.

Conversely you will want a diffused (rough semi transparent surfaced) RGB LED if you install it for direct viewing.

If you have a clear RGB LED and want to see the colours for testing place a diffuser over it e.g. some white tissue paper - otherwise you'll just see the three LEDs directly - you want the combined effect.

Fading RGB LED Arduino clear led

Place a diffuser over the LED to see the "true" (combined) colour:

Fading RGB LED Arduino adding a diffuser

Fading RGB LED Arduino: Connections

Fading RGB LED Arduino: Use an Individual RGB LED

You can either setup an individual RGB LED with four pins on a solderless breadboard; or use  a Keys RGB PCB (as in the images above). Here's connections for an individual RGB LED:

1. Place the RGB LED:

  • Place the RGB LED into the breadboard (flat side is the ground).

2. Place three 220-ohm resistors, one to each of the RGB pins of the RGB LED on the breadboard and connect jumpers to the Arduino.

Connect the following pins of the resistors using jumper wires:

  • Other end of resistor on Red pin to digital pin 9 of the Arduino.
  • Other end of resistor on Green pin to digital pin 10 of the Arduino.
  • Other end of resistor on Blue pin to digital pin 11 of the Arduino.
  • RGB LED Cathode pin to the negative rail of the breadboard.

Fading RGB LED Arduino: Connection Diagram

The flat side of the LED is a common cathode (ground connection). The three other pins are positive voltage pins fed via PWM signals through the resistors.

Fading RGB LED Arduino connection diagram
Image created using Fritzing.

Fading RGB LED Arduino: Use a Keys RGB LED

Alternatively use a Keyes RGB LED mounted on an small PCB (used in the photos). This includes the three current limiting resistors (these are 150 ohm each). So all you need to do is connect 4 wires; 3 PWM signals and one ground connection (labelled '-') to the Arduino - You don't need a solderless breadboard.

Fading RGB LED Arduino: How it works

Controlling a single LED for fading is straightforward. The program incrementally increases the LED's pulse-width modulation (PWM) signal over time. This makes the LED gradually brighter. Only one color is involved, so the process is simple.

Keeping the same colour profile during fade

When fading three LEDs that can each change color, the approach is more complex. Each LED has its own PWM signal to control brightness. Simply increasing all three PWM signals equally would change the overall color as it gets brighter.

To maintain a consistent color mix, the PWM values for each LED must increase proportionally as they approach the intended final brightness. This preserves the same ratio of colors throughout the fade, even as the overall brightness rises.

Say you have 100 steps to get to the final output, and one LED needs a final  value of 10 the second 200 and the third 100. To arrive at these values after 100 steps needs increments of:

    LED1 10/100
    LED2 200/100
    LED3 100/100

Using these fractions of increments means you end up with  10, 200, and 100 as the final PWM outputs when the final step count of 100 is reached. It also means that the proportion of fractional additions each time is the same as the final output ratios - meaning the colour is the same throughout.

You can do this with floating point values and it does work well. This can also be done with fixed point to save memory - if you think about it!

Fading RGB LED Arduino: Breathing Ex1 using floats

Here is the example sketch for Fading RGB LED Arduino breathing LEDs.

Note how the "breathing" effect is made by changing the rate of update within the fadeInOut function over a span of thirds of the step change - and you can change these rate for fade-in and fade-out for yourself.

Using float type variables allows the fractional increments work  very well but if you don't use floats anywhere else in your program it is wasteful of space (~3k). It would be better, in that case, to use a fixed point number representation.

// Arduino RGB LED fade by John Main (c) TronicsBench.com
// Free for non-commercial use.

static const int  MAX_COL_VAL  = 150; // Brightness
static const int  NUM_STEPS    = 300;
static const int  PEAK_HOLD_MS = 150;

static int redPin = 9;     // Red LED pin
static int greenPin = 10;  // Green LED pin
static int bluePin = 11;   // Blue LED pin

static float red=0, green=0, blue=0;

void setup() {
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);


void fadeInOut(float dRed, float dGreen, float dBlue, int sign) {

  for( int i=0; i<=NUM_STEPS; i++) {

    red   += dRed*sign;
    green += dGreen*sign;
    blue  += dBlue*sign;

    analogWrite(redPin,   round(red) );
    analogWrite(greenPin, round(green) );
    analogWrite(bluePin,  round(blue) );

    //Control rates
    float  div=1;
    if (NUM_STEPS>190) div=1.4; // Speed up for less flicker
    if(sign==1) {  // Up
          if (i<256/3)     delay(8/div);  // First third.   Attack.
     else if (i<(256*2)/3) delay(7/div);  // Second third.
     else                  delay(3/div);  // Last third.

    } else { // Down
          if (i<256/3)     delay(5/div);  // First third.   Decay.
     else if (i<(256*2)/3) delay(7/div);  // Second third.
     else                  delay(9/div);  // Last third.

  } // For loop.

void loop(void) {

  // Generate random RGB values
  int targetRed = random(0, MAX_COL_VAL);
  int targetGreen = random(0, MAX_COL_VAL);
  int targetBlue = random(0, MAX_COL_VAL);

  float fadeDeltaRed   =  (float)targetRed/NUM_STEPS;
  float fadeDeltaGreen =  (float)targetGreen/NUM_STEPS;
  float fadeDeltaBlue  =  (float)targetBlue/NUM_STEPS;


Written by John Main who has a degree in Electronic Engineering.

Note: Parts of this page were written using claude-instant as a research assistant.


Have your say about what you just read! Leave me a comment in the box below.

Don’t see the comments box? Log in to your Facebook account, give Facebook consent, then return to this page and refresh it.

Privacy Policy | Contact | About Me

Site Map | Terms of Use