Arduino – LED logarithmic fade

Yet another Arduino LED fade effect. Similar to Arduino – LED linear fade. However, this one is using logarithmic scale for the delay time. It gives a nice “breathing” LED light effect. With properly adjusted settings it can look like a sleep LED effect in a macbook. This example Arduino project lights the basic LED connected in series with resistor to pin 11. The complete code is on GitHub, here.

Logarithmic Fade effect changes the LED brightness in a logarithmic scale. It means that the delay time is a result of calculation of natural logarithm for all steps (see the chart below).

You can change the speed of the fade effect by setting the extra linear delay time (microseconds) like in example code below.

LogarithmicFade fade(led, 1000);

Parts List

Software

This code is written in C++ and can be compiled using an Arduino IDE. All information about how to compile this project is here.

#include <stdint.h>
#include <math.h>

/**
 * The instance of this class can control single LED.
 * - on, off, toggle (any digital pin)
 * - brightness (only PWM pins; i.e. for Arduino Uno: 3, 5, 6, 9, 10, 11)
 */
class BasicLed {
public:
  BasicLed(uint8_t pin): pin_(pin) {
    pinMode(pin, OUTPUT); 
  }
  /* Light the LED up */
  void on(void) {
    digitalWrite(pin_, HIGH);
  }
  /* Turn the LED off */
  void off(void) {
    digitalWrite(pin_, LOW);
  }
  /* Toogle LED on/off */
  void toggle(void) {
    digitalWrite(pin_, !digitalRead(pin_));
  }
  /* Set LED brightness from range <0, 255> */
  void setBrightness(uint8_t value) {
    analogWrite(pin_, value);
  }
private:
  uint8_t pin_;
}; /* End of class BasicLed */

class LogarithmicFade {
public:
  LogarithmicFade(const BasicLed& led, uint16_t extra_delay_us = 3000) : 
    led_(led), extra_delay_us_(extra_delay_us) {}
  /* fade-in */
  void in(void) {
    for (int16_t i = 0; i < 255; ++i) {
      led_.setBrightness(i);
      sleep(i);
    }  
  }
  /* fade-out */
  void out(void) {
    for (int16_t i = 255; i >= 0; --i) {
      led_.setBrightness(i);
      sleep(i);
    }
  }
private:
  BasicLed led_;
  uint16_t extra_delay_us_;
  
  void sleep(uint8_t i) {
    delayMicroseconds((uint16_t)(log(1. / (i + 1)) + 5.) * 1000);
    delayMicroseconds(extra_delay_us_);
  }
}; /* End of class LogarithmicFade */

BasicLed led(11);
LogarithmicFade fade(led);

void setup() {
  // do nothing
}

void loop() {
  fade.in();
  fade.out();
}

Leave a Comment