Arduino code for smooth fading rgb leds using pwm

Code / Program for Smoothly Fading of many RGB colours using an Arduino PWM and a non blocking program!

Ok so some of you may have seen or used my previous Arduino LED Fade example. It was just banged together to show that fading could be done very smoothly between colours using the pwm. Seeing as that program was so poor and didn’t allow for the LED function to be run with any other program via its extensive use of the delay(); function which is a big NO NO! I decided I’d bang this together quickly for anyone interested. It uses a non blocking style program by counting out timers to run functions on time and only when needed. I hope it is easy to follow.

Please let me know if/where you use it and post any questions or whatever in the comments. Happy Arduinoing!

/*
  Updated Fade RGB LED Smoothly through 7 colours
  Fades an RGB LED using PWM smoothly through 7 different colours pausing for 1 seconds on each colour.
  Re-writted code to non blocking program using timers.
  
  Connect an common Cathode RGB LED with appropriate resistors on each anode to your Arduino Uno; 
  Red to pin 6, Green to pin 5, Blue to pin 3, Cathode to GND.
  
  Developed for Arduino Uno by Joshua David - TechHelpBlog.com
   
  Please Feel Free to adapt and use this code in your projects. 
  Contact me at techhelpblog.com and let me know how you've used it!  
*/

#define GRN_PIN 5
#define RED_PIN 6
#define BLU_PIN 3

byte RED, GREEN, BLUE; 
byte RED_A = 0;
byte GREEN_A = 0; 
byte BLUE_A = 0;
int led_delay = 0;
byte colour_count = 1;                //Count the colours out
#define colour_count_max 7              //Set this to the max number of colours defined
#define colour_delay 4000             //Define the delay between changing colours in ms
#define time_at_colour 1000           //Time to stay on a colour in ms

//Some Time values
unsigned long TIME_LED = 0;
unsigned long TIME_COLOUR = 0;

//Define Colours here.
//Blue
#define C1_R 0
#define C1_G 0
#define C1_B 255
//Red
#define C2_R 255
#define C2_G 0
#define C2_B 0
//White
#define C3_R 255
#define C3_G 255
#define C3_B 255
//Orange
#define C4_R 255
#define C4_G 186
#define C4_B 0
//Light Blue
#define C5_R 0
#define C5_G 168
#define C5_B 255
//Purple
#define C6_R 255
#define C6_G 0
#define C6_B 255
//Yellow
#define C7_R 255
#define C7_G 250
#define C7_B 0

void setup()
{

  //Assign initial values
  RED = C1_R;
  GREEN = C1_G;
  BLUE = C1_B;
  //Get the led_delay speed
  led_delay = (colour_delay - time_at_colour) / 255; 

  analogWrite(GRN_PIN, 0);
  analogWrite(RED_PIN, 0);
  analogWrite(BLU_PIN, 0);

}

void loop()
{

  //Rest of your program - Avoid using delay(); function!

  if(millis() - TIME_LED >= led_delay){
    TIME_LED = millis();

    //Run the LED Function to check and adjust the values
    LED();
  }

  if(millis() - TIME_COLOUR >= colour_delay){
    TIME_COLOUR = millis();

    //Run the Colour Change function
    COLOUR();
  }

}

void LED()
{

  //Check Values and adjust "Active" Value
  if(RED != RED_A){
    if(RED_A > RED) RED_A = RED_A - 1;
    if(RED_A < RED) RED_A++;
  }
  if(GREEN != GREEN_A){
    if(GREEN_A > GREEN) GREEN_A = GREEN_A - 1;
    if(GREEN_A < GREEN) GREEN_A++;
  }
  if(BLUE != BLUE_A){
    if(BLUE_A > BLUE) BLUE_A = BLUE_A - 1;
    if(BLUE_A < BLUE) BLUE_A++;
  }

  //Assign modified values to the pwm outputs for each colour led
  analogWrite(RED_PIN, RED_A);
  analogWrite(GRN_PIN, GREEN_A);
  analogWrite(BLU_PIN, BLUE_A);

}

void COLOUR()
{

  //Increment the colour by one or go back to 1 if maxed out
  if(colour_count < colour_count_max) colour_count++;
  else colour_count = 1;

  if(colour_count == 1){
    RED = C1_R;
    GREEN = C1_G;
    BLUE = C1_B;
  } else if(colour_count == 2){
    RED = C2_R;
    GREEN = C2_G;
    BLUE = C2_B;
  } else if(colour_count == 3){
    RED = C3_R;
    GREEN = C3_G;
    BLUE = C3_B;
  } else if(colour_count == 4){
    RED = C4_R;
    GREEN = C4_G;
    BLUE = C4_B;
  } else if(colour_count == 5){
    RED = C5_R;
    GREEN = C5_G;
    BLUE = C5_B;
  } else if(colour_count == 6){
    RED = C6_R;
    GREEN = C6_G;
    BLUE = C6_B;
  } else if(colour_count == 7){
    RED = C7_R;
    GREEN = C7_G;
    BLUE = C7_B;
  }
}


Share

Tags: , , , , ,

10 Responses to “Arduino code for smooth fading rgb leds using pwm”

  1. Sam January 8, 2014 at 8:24 am #

    Hi, this code is exactly what I’m looking for, as I need to be able to switch between a rgb mode that fades, and a rgb mode that reacts to music. Already have the music mode working, but the fade mode uses delays which means it often misses the button press. Only problem is my LEDs use a common anode pin, could I have some help on how to alter the code for it to work?

    thanks

    • Josh January 22, 2014 at 1:50 am #

      Glad it helps you out mate! I hate using Delays in code. Have you considered using an interrupt for your button presses? It’s pretty easy with Arduino. I’m about to post a example interrupt modification to the ArduinoIR library. check that out might help.

  2. Tyler October 1, 2014 at 2:37 am #

    This isn’t quite as detailed as the above post. I used it to test some RGB LEDs I purchased

    float fadeSpeed = 4; //fadespeed between each PWM step. should be the total time needed from one color to another divided by the difference between maxFade and minFade.
    int minFade = 5; //minimum brightness. should be positive integer, and above zero to avoide flickering.
    int maxFade = 255; //max brightness. in most cases when this value is too low pin 10 will stay on constantly. must be below 256

    void setup() {
    pinMode(11, OUTPUT); //declare pins as outputs
    pinMode(10,OUTPUT);
    pinMode(9, OUTPUT);
    analogWrite(11, minFade); //turn on each LED so starting is smoother.
    analogWrite(10, minFade);
    analogWrite(9, minFade);
    }

    void loop () {
    for(int i=maxFade; i>=minFade; i–) {
    analogWrite(11, i); //pin 11 starts at maxFade and fades to the minFade integer
    analogWrite(10, -i); //pin 10 starts at minFade and fades to maxFade integer
    delay (fadeSpeed);
    }
    for (int i=minFade; i=minFade; i–) {
    analogWrite(9, i); //fading down pin 9
    analogWrite(11, -i); //fading up pin 11
    delay (fadeSpeed);
    }
    }

  3. Jacob February 4, 2015 at 3:30 am #

    Hi Josh,

    this code is brilliant, but is there anyway that I can make the LED-fade even slower? I’m a complete beginner, so you must excuse me if theres a obvious method i haven’t seen.

    • Josh September 18, 2015 at 11:38 pm #

      Hi Jacob, Sorry for my delay in reply. Yes you can adjust it easily just change these settings shown below that are at the top of the arduino code. they are in milliseconds so 1000 = 1 second.

      #define colour_count_max 7 //Set this to the max number of colours defined
      #define colour_delay 4000 //Define the delay between changing colours in ms
      #define time_at_colour 1000 //Time to stay on a colour in ms

  4. Matt February 11, 2015 at 9:18 pm #

    Good work, your code works great. – I am using it in a project I am building with my son.

  5. Haron February 16, 2015 at 6:45 am #

    Hey Josh!

    Thank you for the code. It’s just beautiful, it works like a charm. I’m wokring on the same thing as the oter user Sam. And did use the interrupt for a button.

    I’ve been working with breaking this problem a while now. Finally i can die in peace 😉

  6. Josh September 18, 2015 at 11:40 pm #

    Cool to see my code used in projects! Awesome.

Trackbacks/Pingbacks

  1. Program for Fading between colours smoothly using PWM an RGB LED and an Arduino Uno | Tech Help Blog - October 23, 2013

    […] UPDATE! See my updated version of this code here […]

  2. Pumpkin candle replacement 2014 edition (#pumpkin_led) | Facelesstech - October 31, 2014

    […] know where to start writing the code. after searching round on google I found this really cool blog post with just what I was looking for. I need the fade code to have no delays in it since I was wanted […]

Leave a Reply