Check the 34 other Arduino tutorials

#3 · Fade a LED with pulse width modulation (PWM)


Introduction

You already know how to make an LED blink. We now go one step further: make the LED smoothly turn on and off (so-called fading). For this we are going to use a technique called PWM (Pulse Width Modulation). Became curious? Then let's get started! 😃

Course material

At the bottom of this page you'll find the course material button. This button allows you to download the code, circuit diagram and other files relevant to this Arduino tutorial.

PWM - Pulse Width Modulation

If you provide a light bulb with less power, it shines less brightly. This works differently with an LED, it actually only has two states: on or off. How can we ensure that it can appear less brightly? The solution is to make the LED blink very quickly, so fast that our eye can no longer see it. This technique is called Pulse Width Modulation and is often abbreviated as PWM.

In our case, the pulse width is the time that the LED is lit. By making this time longer, the LED lights up brighter. This is shown schematically in the image below.

PWM - Pulse Width Modulation
Schematic representation of PWM

Four repetitions are drawn consecutively for each Duty Cycle. The length of each part is not important for now.

At the top you see the 0% Duty Cycle at 0 Volts. In this situation, no current flows through the LED and it is turned off. At the bottom is the 100% Duty Cycle at 5 Volts. In this situation, the LED lights up.

The three middle steps are new. In the 25% Duty Cycle you see that 25% of the time, the LED gets 5 Volts. This means that the LED will light up 25% of the time. In the middle step you will see power going to the LED 50% of the time. In this case, the LED lights up 50% of the time.

Suppose we are going to make the total duration of one repetition very small, for example 10ms. Our eye can no longer detect the blinking and the LED seems to burn less brightly.

Earlier I mentioned that this technique is called Pulse Width Modulation. If you look at the diagram you will see that with each Duty Cycle the width of each pulse increases. I'm going to show you how to do this on your Arduino.

🎓 We take the 75% Duty Cycle, each repetition lasts 4 seconds. Can you think of how many seconds the LED is on and off?

The circuit

Not all pins on the Arduino support PWM. This only applies to the Pins marked with a ~. More information about which pins support PWM can be found on the Arduino website.

Arduino PWM pins
Pin 11, 10 and 9 support PWM (Pulse Width Modulation)

In this circuit we see that the anode of the LED is connected via a resistor to pin 11 on the Arduino. Then the cathode of the LED is connected to the ground (GND) on the Arduino

Arduino met LED
The circuit for PWM on breadboard

Arduino Code

The first lines of the code speak for themselves. We set the correct LED pin, and indicate that we want to use it as OUTPUT.

1 // Define the pin used for our LED
2 int ledPin = 11;
3 
4 // The setup() function only runs when the program starts
5 void setup() {
6     // Initilize the digital pin LED_BUILTIN as output
7     pinMode(LED_BUILTIN, OUTPUT);
8 }

loop()

1 // The loop() function runs infinitely
2 void loop() {
3 
4     // Fade in
5     for(int ledVal = 0; ledVal <= 255; ledVal +=1) {
6         analogWrite(ledPin, ledVal);
7         delay(15);
8     }  
9 
10     // Fade out
11     for(int ledVal = 255; ledVal >= 0; ledVal -=1) {
12         analogWrite(ledPin, ledVal);
13         delay(15);
14     } 
15     
16     // Pause for 1 second (1000 milliseconds)
17     delay(1000);
18 
19 }

The loop() function consists of 3 parts:

  • Fade in
  • Fade out
  • Pause

For-loop

1 // Fade in
2 for(int ledVal = 0; ledVal <= 255; ledVal +=1) {
3     analogWrite(ledPin, ledVal);
4     delay(15);
5 } 

To make the LED glow more and more brightly, we will increase the value of pin 11 every 15ms until 255 is reached. We do this with a 'for loop'.

The for function consists of three parameters:

  • start value
  • condition
  • step size

In the above code we define a variable ledVal of type integer (i.e. an integer) and set the start value to 0.

As a condition to be allowed to do another repetition, we give that the value must be less than or equal to 255: ledVal <= 255.

We want to increment ledVal by 1 each step which we write as ledVal +=1.

💡 A shorter spelling for this is ledVal++

analogWrite()

In the previous lesson we used digitalWrite which could only send two values to a pin: HIGH or LOW. For PWM we are going to use analogWrite.

We write the analog value of ledVal with the analogWrite function to the ledPin. This PWM value is between 0 (always off) and 255 (always on).

We then wait 15 milliseconds for the next step to be performed.

For-loop for fade-out

1 for(int ledVal = 255; ledVal >= 0; ledVal -=1) {
2     analogWrite(ledPin, ledVal);
3     delay(15);
4 }

The code for the fade out is almost the same. The only difference is that we now go from 255 back to 0.

🎓 Do you see the difference between the fade-in and fade-out code?

1 delay(1000);

Then we wait 1000 milliseconds (1 second) before starting over again.

Uploading code to the Arduino

Now our program is ready to upload to the Arduino. First we have to connect our Arduino to the computer with the USB cable. Make sure you've selected the correct board in the IDE:

Tools ▸ Board ▸ Arduino/Genuino UNO

and the correct port:

Tools ▸ Port

If you are not sure which port to use, try them all until you can successfully upload your code.

The top left shows a round button with a checkmark. By pressing this button you tell the IDE to verify your code for possible errors. The IDE only checks if it can read your code. It does not check if you have written correct code for what you are trying to program.

If everything works the IDE shows the Compiling completed message. You can now upload your code by pressing the round button with the arrow to the right. The uploading is complete when the Avrdude done. Thank you. messages appears. Your program will immediately start after uploading. As a result you should now see your LED fading with 1000ms intervals.

#3 &middot; Fade a LED with pulse width modulation (PWM) schakelschema

Bas van Dijk

About Bas on Tech


My name is Bas van Dijk, entrepreneur, software developer and maker. With Bas on Tech I share video tutorials with a wide variety of tech subjects i.e. Arduino and 3D printing.

Years ago, I bought my first Arduino with one goal: show text on an LCD as soon as possible. It took me many Google searches and digging through various resources, but I finally managed to make it work. I was over the moon by something as simple as an LCD with some text.

With Bas on Tech I want to share my knowledge so others can experience this happiness as well. I've chosen to make short, yet powerful YouTube videos with a the same structure and one subject per video. Each video is accompanied by the source code and a shopping list.