Arduino Sensors & Actuators guide series

How to make an LED fade on and off

In this article, you will learn how to make an LED fade on and off instead of simply blinking.

In the previous tutorial, you learned how to setup a simple circuit in which an LED blinks on and off. The Arduino sketch that drove the circuit simply wrote a HIGH or LOW value to the digital output pin 9, and the LED was turn on or off accordingly.

In this article, you will learn how to make the LED not blink but fade on and off. You will keep the exact same circuit, and only change the sketch to make this happen.


I have recorded a short video to show you how to run this experiment inside a simulator. This is the best way to experiment with the Arduino if you don't have the real thing. Be sure to read the complete tutorial to understand the details of the circuit and the sketch. 

If you are in a hurry, watch this video first.

The wiring diagram

Here is the wiring diagram, in case you need it:

The wiring diagram for the "blinking LED" experiment.

The sketch

And, here's the new sketch (slightly modified from the sample in the Arduino IDE which you can load by going to File > Examples > 01.Basics > Fade)  (or you can get this sketch from Github):

int led = 9; // the pin that the LED is attached to
int brightness = 0; // the bigger this number, the brighter the LED is			
int fadeAmount = 5; // the bigger this number, the faster the the LED will fade on or off
// the setup routine runs once when you press reset:
void setup() {
  pinMode(led, OUTPUT); // declare pin 9 to be an output:

// the loop routine runs over and over again forever:
void loop() {
  analogWrite(led, brightness); // set the brightness of pin 9:
  brightness = brightness + fadeAmount; // change the brightness for next time through the loop:
	// reverse the direction of the fading at the ends
  // of the fade:
  if (brightness == 0 || brightness == 255) {
    fadeAmount = -fadeAmount ; 
  delay(10); // wait for 10 milliseconds to see the dimming effect

The most important difference between this sketch and the blinking LED sketch, is that we now use analogWrite instead of digitalWrite

While digitalWrite can only output a HIGH or LOW value, analogWrite allows us to output values between 0 and 255.

The analogWrite function uses a technique called "Pulse Width Modulation", or PWM for the abbreviated short. A the function takes in one argument, a number from 0 to 255. The Arduino will then convert this value into a square waveform. The square waveform has a high of 5V and a low of 0V, but depending on the PWM value we set in analogWrite, the duration of HIGH varies.

When we set PWM value to 255, the square wave is at HIGH permanently and the connected LED is at its brightest setting.

When we set PWM to 0, the square wave is at 0V permenently, and the LED is switched off.

In-between values, like 120, result to the square wave being HIGH for around half of the period, and LOW for the rest of the period. That way, the LED is around half as bright as it can be. 

The amount of time of a period that a PWM signal is at HIGH is known as the "duty cycle".

Using PWM, a simple device like the Arduino can simulate an analog output signal, which as a real analog effect on a device like an LED or a motor. PWM gives us a simple way to set an LED to 1/3 (or any other fraction) of its full potential brightness.

Similarly, we can control the speed of a motor or the loudness of a speaker.

In this video, I show what a PWM signal that is produced by an Arduino looks like in the oscilloscope. This signal causes the LED to fade on/off.


Do you think that the oscilloscope is too complicated, too expensive and has no place on your workbench? You're wrong!

With this course, you will learn how to use the oscilloscope and take your understanding of electronics to the next level.

In the loop() function, we first set the brightness of the LED, using the analogWrite() function, by selecting the pin to which the LED is connected, and the 'brightness'.

Brightness is a global variable of type integer that is initialised to be 0 when the program starts. So, the first time that the program runs in the Arduino, this instruction will look like this:

analogWrite(9, 0);

In the next instruction, after the comment, we calculate a new value for the brightness. The new brightness is equal to the old brightness plus the fadeAmount, the value stored in another global variable that we set to be 5 in the very start of the program. So, the first time the program runs, this instruction will look like this:

brightness = 0 + 5;

Therefore, brightness will now become 5.

Next, we use a control structure to determine if we have reached a limit for the brightness, either the lower limit (0) or the upper limit (255). If we have, then we switch the sign of the fadeAmount variable. The effect is that if the LED was becoming brighter because the fadeAmount was positive, then once it reaches it brightest setting (when brightness equals 255), then fadeAmount will be changed its negative (-5) and brightness will start moving towards zero.

In the statement:

if (brightness == 0 || brightness == 255)

...the part within the parentheses is called a "condition". The "==" tests for equality. You could test for "greater" with ">" or "less" with "<", as well as for a variety of other conditions.

In the same statement, the "||" is the boolean operator "OR". You can join two conditions together, and the result will be true if one of them is true. So, in our example, whatever is between the curly brackets will be executed if either brightness is zero OR brightness is 255.

Ready for some serious Arduino learning?

Start right now with Arduino Step by Step Getting Started

This is our most popular Arduino course, packed with high-quality video, mini-projects, and everything you need to learn Arduino from the ground up.

We publish fresh content each week. Read how-to's on Arduino, ESP32, KiCad, Node-RED, drones and more. Listen to interviews. Learn about new tech with our comprehensive reviews. Get discount offers for our courses and books. Interact with our community. One email per week, no spam; unsubscribe at any time

{"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}