PWM – Pulse-width modulation

Working with digital signals is as straightforward as it gets. It can be either on or off, 1 or 0. This is best shown in the most simple Arduino project, a blinking LED . When the LED isn’t shining, the digital signal is off. When it’s shining, the signal is on. But what if we wanted to work with analog signals such as the speed of a motor? We would then use something called pulse-width modulation, or PWM for short.

What is PWM?

In simple terms, PWM is a type of digital signal that allows us to work with analog devices. Since it’s a digital signal, it “fakes” results to make them seem like analogs. It does this by applying regulated voltage in short bursts we call pulses. The signal can only be high (usually 5V) or low (ground). PWM makes the signal high and then low during a consistent period. This allows it to be on a virtually infinite number of places between low (0) and high (1).

Looking at the image below, you can see how the signal is sent in pulses. They look squared because the signal can be either high or low. That’s why there are no smooth slopes as there are no “smooth” transitions between the two power states.

Some basic terminology

Now that we know what PWM is and what it looks like, let’s get into more details about how it works.

In PWM, the minimum and maximum voltages will limit the oscillation of the pulses. In other words, they will limit how high the pulse can go. The space between the minimum and maximum voltage is called amplitude.

The interval between the beginning of one pulse and the beginning of another is called a cycle.

One cycle equals one repetition – a pulse cannot happen more than once in a cycle. The period is the amount of time it takes for one cycle to finish. Frequency is measured by dividing 1 by period. This tells you how many cycles are in a given time, which is often a second.

Duty cycles

Pulse-width modulation has a very important concept that makes it work the way it does, called a duty cycle. It represents the amount of time the signal is high during a period. This is called “on” time. Likewise, the amount of time the signal is low is called “off” time. The duty cycle is measured in percentage. When a digital signal is on half of the time, and off the other half, we would say it has a duty cycle of 50%. The on and off periods would be identical lengths so it would look like an ideal square wave. If the duty cycle is, let’s say, 75%, the digital signal will be high longer. If it was 25%, it would be high much shorter. You can see a graphical representation of these situations in the illustration below.

You’ll notice we haven’t added 0% and 100% duty cycles in the illustration, and there’s a simple reason why. Both representations would be just a straight line, one high and one low. 100% duty cycle line would be the same as setting the voltage to 5 volts, and 0% grounding the signal.

Calculate the percentage of the duty cycle

Knowing the percentage of duty cycle is a must when working with PWM, but how can we find it out? To calculate it, you will first need to know how long your period is. To make our calculations simple, we used 10 ms for the period in our example. The next thing you’ll need to know is either “on” or “off” time. In our example, we set the “on” time at 6 ms, meaning that the “off” time is 4 ms.

To get the percentage of duty cycle you just need to divide the “on” time by period. This is the same as you would calculate any percentage. In other words, dividing x by 100, where x is a variable. So in our case, we would divide 6 (our “on” time) by 10 (our period) and get 0.6 as a result. Now we just need to multiply it by 100 to get the result of 60%. Thus, our duty cycle is 60%, meaning that our signal is high 60% of the time.

You can also multiply the “on” time by 100 before you divide it by period. This saves you some time when calculating, and makes everything more legible. The formula in our case would then be x = (6*100)/(10) = 60%.

The illustration below will visually represent the calculation.

Calculate the output voltage

The voltage value in PWM will depend on the difference between the time the signal was high and the time it was low. If it was high for a longer period, the voltage value will be higher as well. What do we mean by that? How can we calculate it then? Let’s look at another illustration.

Here we can see our signal oscillates between 0V and 5V. Our duty cycle is 60% meaning our signal is high 60% of the time. We must have these two values to calculate the output voltage. To find the value of it, we need to multiply the maximum voltage by the duty cycle. So in our example, that would be 5 * 60%, resulting in 3V.

If you were to increase the duty cycle, the output voltage would increase as well. Similarly, if you were to decrease the duty cycle, the output voltage would decrease. You’ll see a more hands-on approach a bit later in a short example we prepared.

The duty cycle doesn’t change with frequency

Another thing to keep in mind when working with PWM is the frequency at which the pulses occur. The duty cycles will appear shorter and repeat much faster if the frequency is increased. Similarly, if the frequency is decreased, the duty cycles will appear long and repeat at a slower rate. An important thing to note is that the duty cycle remains constant, even though the pulses look different depending on the frequency.

Let’s say we have two 50% duty cycles, one at 10 kHz frequency and the other at 1000 kHz. You’ll notice that the one at a higher frequency appears smaller. However, if you looked closely at both cycles, you’d see that both have their signal high and low equally. The signals are high half of the time and low the other half. Thus, even though the duty cycles look different, they are still equal.

PWM on Arduino boards

Many modern microcontrollers have integrated PWM controllers exposed to external pins. Arduino is no different. It has a built-in function “analogWrite()” used for generating PWM signals. Despite the function name, the output is still a digital signal. This function can be given values from 0 to 255. Depending on the duty cycle percentage, we would write:

analogWrite(0) for a signal of 0% duty cycle,

analogWrite(127) for a signal of 50% duty cycle,

analogWrite(255) for a signal of 100% duty cycle.

On most Arduino boards the PWM pins will be 3, 5, 6, 9, 10, and 11. They are usually marked with a tilde sign (~) or an apostrophe (‘).

Connecting the circuit

Let’s build a small Arduino project to understand better what PWM does. For this project, you will need:

• an Arduino board
• a generic LED (any color)
• a single-turn potentiometer
• a 220-ohm resistor
• a generic breadboard
• some generic jumper wires

First, we’ll add all the jumper wires to our Arduino board. Add a wire to digital pin 6, power pins 5V and GND, and an analog pin A0. Next, we’ll add an LED by connecting the ground leg to J2, and the other leg to J1. The resistor is next connected to holes I2 and I6. The last component we’ll add is the single-turn potentiometer, connecting it to holes J9, J11, and J13. Once we have all components connected, we’ll start connecting the wires. Take the wire connected to digital pin 6 and connect it to the H1 hole. Next, connect the 5V wire to the hole F13. GND wire will be connected to hole F6, and A0 to F11. We’ll finish the circuit by adding another wire, in holes G6 and G9. Once everything is connected, it should look something like the image below.

The code

If everything is correct, you will be able to change the brightness of the LED by turning the knob on the potentiometer.

Troubleshooting

If the LED is not working, check if you have everything connected properly. If everything is fine, try a different LED. The one you’re using might be burnt. If it’s still not working, the issue could be in the code. Look through it to see if you can spot something different, or just copy and paste it in Arduino IDE. Make sure everything is set up correctly in Board and Port options in the Tools on the taskbar.

Real-world applications

So what are some more real-world applications of PWM? Think of your computer and the fans inside it. They are constantly spinning. If your computer starts doing something that requires more energy, the fans will start spinning faster to cool it down. If it’s not doing anything complex, the fans will spin much slower as your computer doesn’t need cooling as much. The fan and its motor won’t stop instantly during the duty cycle’s “off” time because of inertia. It only slows a tiny bit before the power reapplies. That is why no abrupt stop is experienced with motors driven by PWM.

As you can see, pulse-width modulation is a very clever way to use electricity. One thing to keep in mind is that the term duty cycle used with PWM is not tied exclusively to it. It is used elsewhere in electronics, and in every case, it means a comparison of “on” versus “off”.

Knowing PWM becomes crucial the more you learn about Arduino and electronics. If you want to get more hands-on experience with it, check our tutorials page to find projects with PWM.