An Arduino is a digital device, i.e it treats everything as ON(5v) or OFF(0v), so how can we use it to generate analogue signals and voltages which are between 0 and 5v? The answer to this is PWM which stands for Pulse Width Modulation. Don’t get intimidated by the word, it is actually a very simple and elegant technique and furthermore is implemented into the Arduino in a very easy to use way.
In this tutorial, we will learn about PWM, and how it can be used with an Arduino to control the brightness of an LED. Let’s get started!
How does PWM work?
PWM which stands for pulse width modulation is a technique used to convert digital voltages to “apparent” analogue voltages. A microcontroller/microprocessor is a digital device which can only output 0 and 5v. Because of this, any device being powered by them can either be on or off and in many cases, this is not desirable. An example is an LED. We do not want the LED to just be on or off. We might require it to be on, gradually decreasee its brightness until it is fully switched off. This is where PWM steps in.
In this technique, a pin is selected and then its voltage is switched from 5v to 0v and back VERY VERY FAST. This gives the effect of a voltage between 5 and 0 begin present. The key to this is that it must be done MILLIONS OF TIMES a second(at least) without which the desired effect will not be produced. Here is an example of PWM where 2.5v is required. This is exactly in between 0 and 5v. Here is how the pin will be switched for this-
The pin is set to 5v and then 0v, but for the same amount of time. This ratio of 1:1 gives the effect of 2.5v begin present. Just remember that this “amount of time” is not more than a FEW MICROSECONDS.
In this graph, the pin is set to 5v for twice as long as it is set to 0, i.e the ratio of the times is 2:1. This gives the illusion of 3.3v being present.
Here is another example, but this time the voltage is set to 0v for twice as long as 5v. This gives the illusion of 1.67v being present as the ratio is 1:2.
Now that you have understood the theory behind PWM, its time to make a project out of it. Let’s begin.
Step 1: Gathering the parts
In this step I will be listing all the necessary parts you require and how you can get them.
- USB cable
These parts can be bought from any online electronics distributor or parts-seller but for your convenience I have listed some places at the end of this tutorial. You might probably even have these parts already if you have read my blog on getting started with Arduino.
Step 2: Assembling everything
Not all of the pins on the Arduino are PWM enabled and it has a limited number of pins which can perform pwm by default. Here is a list of the pins which support PWM on various Arduinos. Another way to differentiate between PWM-enabled and regular pins is by searching for a curly squilda(~) mark next to the pin number. If the ~ mark is present next to the pin, it is PWM capable otherwise it is not.It is possible to do PWM on all the pins by writing the code accordingly, but it is not recommended as the Arduino will not be able to do anything else(it will be stuck controlling the state of the pin). Do keep in mind that analogRead pins(pins with an A before them) are not PWM capable.
Wire up the shorter -ve leg(called cathode) of the LED to any GND pin on the Arduino and the longer +ve leg(called anode) to any PWM capable pin. In the below image I have connected it to pin 11 because it is close to a GND pin and this allows me to skip breadboards and connecting wires.
The current will flow from the pin you have connected the anode to towards GND pin via the cathode.
Step 3: Coding and uploading
In this step, we will code and upload the sketch to the Arduino and see how it produces changes in the LED’s brightness. If you are not familiar with how to use the Arduino IDE, please see my getting started blog(It will really help). Here is the code-
Let us understand the code step by step.
In this segment, I create a variable called pwm and give it a value of 11. Replace 11 with whichever pin you have used. I then set the pin to output mode.
Next, I send an analogue value(0 to 255) to the pin using the analogWrite function. The function accepts all whole number values from 0 to 255. Any value higher or lower will result in an error. Any decimal values(float, long) are also not allowed. the value passed represents a voltage between 0 and 5v, where the conversion formula is-
value = (required voltage)*255/5
This can be further simplified to-
value =(required voltage)*51
Using this, you can see that the program first sets the voltage to 5v(or HIGH), waits for 0.75 seconds, sets it to 2.5v, waits once more, sets the voltage to 0v(or LOW), waits one last time and everything repeats. Compiling and uploading the code to your Arduino will confirm this, unless you have made an error(in which case, fix it).
Step 4: Playing around a bit
Now that we have understood the program, let us tweak it and play around a bit.
Try replacing analogWrite(pwm, 255) with digitalWrite(pwm, HIGH). You might see that this does not change the output one bit. The same can be said for analogWrite(pwm, 0) and digitalWriet(pwm, LOW). This is because both mean the same exact thing. analogWrite(pwm, 255) also sets the pin to 5v and digitalWrite(pwm, HIGH) also sets the pin to 5v.
You can try replacing the values to see how the brightness of the LED changes. Try creating a blink program, but with the LED going from off to half brightness instead. Try to make it blink between half brightness and full brightness.
If you are familiar with for loops, try to write a program which causes to LED to gradually fade from off to full brightness and back. There are many experiments which can be done.
Additional Resources(Worthwhile read)
Here are a few online places to buy the parts from. A google search will yield many more.