Fade an LED with Pulse Width Modulation using analogWrite()

Lets expand the repertoire of output that we can use by looking at the function analogWrite().  I experienced much confusion with analogWrite(), because I suspected that it had to do with the analog pins on the Arduino.  The function, however, has nothing to do with the analog pins.

There are 5 pins on most Arduino boards marked with an ‘~’ next to the pin number – these pins can be invoked to rapidly change the power being applied at the pin – this is a technique called pulse width modulation (PWM).

 

You Will Need

  1. LED – any color is fine
  2. 220 Ohm Resistor
  3. Alligator Clip
  4. Glacial ice cubes

Step-by-Step Instructions

  1. Take the short leg of your LED and stick it in the GND pin.
  2. Take either leg of the resistor and place it in pin 9.
  3. Connect the long leg of the LED with the other leg of the resistor using an alligator clip
  4. Plug the Ardunio into  your computer with the USB cable
  5. Open up the Arduino IDE
  6. Go to File > Examples > 01.Basics > Fade
  7. Click the Verify button (Top Left).  The button will turn orange and then blue once finished.
  8. Click the Upload button.  The button will turn orange and then blue when finished.
  9. Watch in mesmerizing amazement as the LED fades in and out.

This image built with Fritzing.

Discuss the Sketch

Below is the sketch in its entirety from the Arduino IDE:

/*

Fade

This example shows how to fade an LED on pin 9 using the analogWrite() function.

This example code is in the public domain.

*/

int led = 9;           // the pin that the LED is attached to

int brightness = 0;    // how bright the LED is

int fadeAmount = 5;    // how many points to fade the LED by

// the setup routine runs once when you press reset:

void setup()  {

// declare pin 9 to be an output:

pinMode(led, OUTPUT);

}

// the loop routine runs over and over again forever:

void loop()  {

// set the brightness of pin 9:

analogWrite(led, brightness);

// change the brightness for next time through the loop:

brightness = brightness + fadeAmount;

// reverse the direction of the fading at the ends of the fade:

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

fadeAmount = -fadeAmount ;

}

// wait for 30 milliseconds to see the dimming effect

delay(30);

}

The sketch starts with the usual multiline comment describing the sketch and how to set up the circuit.  The first block of code we encounter is the declaration and initialization of 3 int variables…

int led = 9;           // the pin that the LED is attached to

int brightness = 0;    // how bright the LED is

int fadeAmount = 5;    // how many points to fade the LED by

The variable names and comments are both descriptive and helpful – remember this when naming and commenting your own code – it is a pillar of success!  The “brightness” variable will store the value of the current brightness of the LED.  “fadeAmount” is the rate at which the LED will fade and brighten. And of course, as the comments explain, “led” is simply the pin number where we have attached our LED (through a 220 Ohm resistor).

Now that we have declared and initialized our variables, we move on to setting up the board with the setup() function…

void setup()  {

// declare pin 9 to be an output:

pinMode(led, OUTPUT);

}

The only thing we do here is set the mode of pin 9 as an OUTPUT using the pinMode() function.  Recall that pinMode() takes two arguments – the pin number and the mode.  In this case we assign the pin number using our variable “led”, which we previously initialized as the number 9.  By now you know that setup() only runs once – the code inside the setup() curly bracket will only be executed a single time by the Arduino. Where the real action happens is in loop().

The first function we encounter is analogWrite().  This function invokes the Pulse Width Modulation capabilities of our Arduino board.  Pulse Width Modulation basically adjusts the power output at the pin.  So you can have a lot of power or a little power applied at the pin, its your call, you just tell the analogWrite() function which pin to modulate and how much power you want applied.  The scale is from 0 to 255 with zero being the lowest power setting and 255 being the highest.  For a discussion of what is actually happening with pulse width modulation check out the further reading section.

As alluded to above, analogWrite() takes two arguments..

analogWrite(pin, value)

You can utilize pins 3, 5, 6, 9, 10 and 11 with analogWrite() on most Arduino boards (there is a “PWM” or ” ~” next to the pin number on the board).  The value range is from 0 to 255.

In this sketch we use the arguments:

analogWrite(led, brightness);

So the first thing we do in the program is we write a value to pin 9 (recall that “led” holds the number 9) where we have our LED attached (through a resistor) – and we set the value to 0.  This will keep our LED dark to start with.

ERRATA:  You can also use pin 9 for PWM.

The next line of code we encounter is:

brightness = brightness + fadeAmount;

      ( 0 )         =      ( 0 )         +       (5)    //these are the values the first time through the loop

 So we take the current value of ‘brightness’ and add the ‘fadeAmount’ to it, then we save this new value back to the brightness variable.  So now the ‘brightness’ variable holds the number 5.

So you can see that we are increasing the brightness variable, this in turn will make the LED brighter – when we start the loop over and use analogWrite(led, brightness) – it will be 5 “levels” brighter than it was before. Then we 5 more, and so, till we have one really bright LED.

You see however, that if this were to continue on, the brightness variable will quickly go over the top range of 255 our analogWrite() limit – not to mention, it won’t fade if the brightness variable only gets brighter.  We need a way to test the value of the brightness variable, and then change it when it gets to it’s limit.

Welcome “if statement”.  The if statement is my favorite function – it can do so much and is so easy to use.  An if statement checks a condition – if that condition is met, then it does something – if the condition is not met, then it does nothing.  That easy.

Lets say you are picking apples.  You have an if statement running in your brain – something like

if(apple is ripe AND not rotten) {

pick apple()

put_in_basket()

}

The condition is what you type inside the parenthesis after the word ‘if’.  Inside the curly braces you type the code that you want to execute if the condition is met.  If the condition is not met, you do not execute the instructions – in the example above you would not want to pick un-ripened or bad apples.

So lets take a look at how the if statement helps us to fade our LED.

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

fadeAmount = -fadeAmount ;

}

The condition here looks a little confusing, but lets walk through it.

For starters the || lines means OR in computer talk.  So this condition says “if the brightness variable equals zero OR if the brightness variable equals 255”.

You probably  noticed the fact that they use a double equal sign – weird eh?  The double equal sign is a comparison operator that asks “are these two values equal”.  The reason we need a double equal sign to do this, is because if we use a single equal sign, then we would be assigning a value to the brightness variable – and we do not want to assign anything – we want to compare! It is a subtle change in syntax but a huge change application. There are several comparison operators that you will use.  Further Reading below has a link to some good reading on them.

brightness = 0  //this statement assigns a value to the brightness variable

brightness == 0 //this statement compares the brightness variable with 0

The condition in an ‘if statement’ will either be TRUE or FALSE.  If it is TRUE, then the code enclosed in the curly brackets will execute.

Let’s say that our brightness variable is all the way up to the value 255.

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

 This condition is met – now what?

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

fadeAmount = -fadeAmount ;

}

All we do is a sneaky change of sign.

fadeAmount = -fadeAmount ;

//applying a negative sign to the variable will change it sign from positive to negative

 So now the fadeAmount variable is negative.  Each time through we will be subtracting 5 from the ‘brightness’ variable – and our LED will start to dim when we write lower values with analogWrite().

The most awesome thing about this clever line of code, is that once the brightness variable gets as low as zero, it will switch the fadeAmount to positive and start the whole process over again!  A fading LED – and easy!

 The final step is to make sure we slow down the fading process wo we use the delay function to make sure we get to see the fading.

 // wait for 30 milliseconds to see the dimming effect

delay(30);

There is this interesting aspect of human vision called “persistence of vision”.  Basically, if something flashes very rapidly – then we don’t perceive it as flashing, we perceive it as a steady image.  Since our microcontroller operates extremely rapidly, all this fading and brightening would be lost to our eyes if we didn’t slow it down with this delay.

Once we get to the end of the sketch we start back at the top of the loop.  We write the level to the LED, we increment the brightness and we check if our brightness is maximized or minimized  and make the appropriate change.

Try On Your Own

  • At the top of the sketch, where the variable “fadeAmount” is declared and initialized, change the value and see what happens.
  • What happens if you reduce the delay time?
  • Can you fade multiple LEDs at the same time? (Hint: you will have to add another variable and use the analogWrite() function twice instead of just once)

Further Reading

installing Arduino libraries

Installing Arduino Libraries | Beginners Guide

IoT sewage project

Pumping poo! An IoT sewage project

ESP32 webOTA updates

How to update ESP32 firmware using web OTA [Guide + Code]

error message Brackets Thumbnail V1

expected declaration before ‘}’ token [SOLVED]

Compilation SOLVED | 1

Compilation error: expected ‘;’ before [SOLVED]

Learn how to structure your code