Fun with Arduino 16 LED (Strip) Fading

In the previous video we used analogWrite() to dim a LED (strip). We can make a fade effect when we gradually increase or decrease the analog output, step by step, with an interval time. A fade is nice for many applications … kitchen counter light, model railway overhead lighting (to gradually shift from night to day or vice versa) and even a red/green track signal has just that little extra eye candy with a short fade.

Read on below the video …

Let’s use a toggle switch for on/off and use the potentiometer to change the target brightness, declared as byte. The intermediate steps on the way to the target we’ll call current, also a byte.

#define SWITCH_PIN      2 // input for toggle switch
#define POTM_PIN       A0 // potmeter analog input 
#define LIGHTS_PIN      6 // output to FET module
#define LED_PIN        A5 // output to LED on switch panel
#define FADE_INTERVAL 100 // [ms] time between fade steps

byte target, current;     // target and current pwm value
unsigned long time_for_fadestep;

void setup() {
  pinMode(SWITCH_PIN, INPUT_PULLUP);
  pinMode(LED_PIN, OUTPUT);
  Serial.begin(9600);
}

void loop() {

  if (digitalRead(SWITCH_PIN) == 0) { // toggle switch ON
    digitalWrite(LED_PIN, HIGH);
    target = map(analogRead(POTM_PIN), 0, 1024, 0, 256);
  }
  else {                              // toggle switch OFF
    digitalWrite(LED_PIN, LOW);
    target = 0;
  }
  
  if (millis() > time_for_fadestep) {
    time_for_fadestep = millis() + (unsigned long)FADE_INTERVAL;
    if (current < target) current++; // shorthand for current = current + 1
    if (current > target) current--; // shorthand for current = current - 1
    analogWrite(LIGHTS_PIN, current);
    Serial.print(target);
    Serial.print("  ");
    Serial.println(current);
  }
}

Note the notation of current++ … it is shorthand for current = current + 1. Likewise current– is short for current = current – 1.

When we toggle the switch, the LEDs start to fade towards the target brightness, which can be changed with the potentiometer … yes, it works fine.

Of course we can play with the FADE_INTERVAL to determine how fast the fading takes place. For kitchen cabinet lighting you’d probably want it to reach the setpoint in just a couple of seconds … with a model railway day / night cycle simulation we probably like the fading to take half a minute or even more. And with a railway red/green signal we probably like it to take about a second. To fine tune such short fades, the steps of the millis() clock may even be too course. If so, we can use the micros() clock in stead. That is done in this example of a red/green signal change with a 1200 microseconds fade interval.

#define SWITCH_PIN       2 // input for toggle switch
#define RED_PIN          5
#define GREEN_PIN        6
#define FADE_INTERVAL 1200 // [us] time between fade steps

byte target_red,   current_red;
byte target_green, current_green;
unsigned long last_fade_time;

void setup() {
  pinMode(SWITCH_PIN, INPUT_PULLUP);
  pinMode(RED_PIN,    OUTPUT);
  pinMode(GREEN_PIN,  OUTPUT);
}

void loop() {

  if (digitalRead(SWITCH_PIN) == LOW) { // switch to GREEN
    target_red = 0;
    if (current_red == 0) target_green = 150;
  }
  else { // switch to RED
    if(current_green == 0) target_red = 255;
    target_green = 0;
  }
  
  if (micros() - last_fade_time > FADE_INTERVAL) { // no issue after 70 min
    last_fade_time = micros();
    if (current_red < target_red) current_red++;
    if (current_red > target_red) current_red--;
    if (current_green < target_green) current_green++;
    if (current_green > target_green) current_green--;
    analogWrite(RED_PIN, current_red);
    analogWrite(GREEN_PIN, current_green);
  }
}

Note that a micros() timer overflows every 70 minutes. That’s why the timer is used with a subtraction … in stead of check if micros() > time_to_fade … we check if micros() – last_fade_time > FADE_INTERVAL. It’s a little less intuitive to read, and also it’s no big deal if once every hour a fade behaves a bit strange, but still … this subtraction is the way to get rid of any timer overflow issue.

Click here if you like to see more of the kitchen lighting project.

Crossing_RealThe next video will be the start of a new project … we’re going to build a model railway crossing. We’ll use a couple of the techniques we have seen before like LEDs blinking (we know how to do that!) and we’ll include some new ones, like train detection and a servo motor that closes the gate. And we’ll find a nice way to easily write code for a system that changes between the states it can be in, depending on events that take place.

— 0 —

 

Advertisements

One thought on “Fun with Arduino 16 LED (Strip) Fading

  1. Hello Rudy,
    with great pleasure I follow your Arduino Fun videos. They are at least as helpful and imaginative as your EEPX videos, which I have always followed.
    At the moment I have also devoted myself to microcontroller and Arduino. My goal is to create a SmartHome system based on openHAB and microcontrollers.
    Here your video Fun with Arduino 16 LED (Strip) fading came just right.
    However, I modified it a bit to make the fading a bit gentler.
    For this I found an interesting website, where you can create a table of values ​​for a pwmfading matrix:
    http://www.aaabbb.de/JNumberTableMaker/pwm_sine_function_table_maker.php

    I then included them in your Arduino sketch see it below.

    I’m looking forward to further episodes of your series.

    Greetings from Erftstadt near Cologne
    Andreas

    #define SWITCH_PIN 2 // input for toggle switch
    #define POTM_PIN A0 // potmeter analog input
    #define LIGHTS_PIN 9 // output to FET module
    #define LED_PIN 13 // output to LED on switch panel
    #define FADE_INTERVAL 10 // [ms] time between fade steps

    int pwmtab[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //Table of a fading characteristic
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //generated via the link above
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
    2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6,
    7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 10, 10, 11, 11, 11, 12, 12, 12, 13,
    13, 14, 14, 15, 15, 15, 16, 16, 17, 17, 18, 18, 19, 20, 20, 21, 21,
    22, 22, 23, 24, 24, 25, 26, 26, 27, 28, 28, 29, 30, 31, 31, 32, 33,
    34, 35, 35, 36, 37, 38, 39, 40, 41, 42, 43, 43, 44, 45, 46, 47, 49,
    50, 51, 52, 53, 54, 55, 56, 57, 59, 60, 61, 62, 63, 65, 66, 67, 69,
    70, 71, 73, 74, 76, 77, 78, 80, 81, 83, 84, 86, 87, 89, 91, 92, 94,
    96, 97, 99, 101, 103, 104, 106, 108, 110, 112, 113, 115, 117, 119,
    121, 123, 125, 127, 129, 131, 133, 136, 138, 140, 142, 144, 147, 149,
    151, 154, 156, 158, 161, 163, 166, 168, 171, 173, 176, 178, 181, 183,
    186, 189, 191, 194, 197, 200, 203, 205, 208, 211, 214, 217, 220, 223,
    226, 229, 232, 236, 239, 242, 245, 248, 252, 255};

    byte target, current; // target and current pwm value
    unsigned long time_for_fadestep;

    void setup() {
    pinMode(SWITCH_PIN, INPUT_PULLUP);
    pinMode(LED_PIN, OUTPUT);
    Serial.begin(9600);
    }

    void loop() {

    if (digitalRead(SWITCH_PIN) == 0) { // toggle switch ON
    digitalWrite(LED_PIN, HIGH);
    target = map(analogRead(POTM_PIN), 0, 1024, 0, 256);
    }
    else { // toggle switch OFF
    digitalWrite(LED_PIN, LOW);
    target = 0;
    }

    if (millis() > time_for_fadestep) {
    time_for_fadestep = millis() + (unsigned long)FADE_INTERVAL;
    if (current target) current = current – 1; // shorthand for current = current – 1 current–
    analogWrite(LIGHTS_PIN, pwmtab[current]);
    Serial.print(target);
    Serial.print(” “);
    Serial.println(pwmtab[current]);
    }
    }

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s