The concept of Pulse-Width Modulation (PWM) is simple: the ratio of “highs” to “lows” in a stream of high-low pulses can produce an analog effect through the digital signal! This is useful, because this means one can control an analog value, such as the brightness of an LED or the speed of a motor, through the analog value time, without having to adjust the voltage supplied to that component. Essentially, this makes a PWM signal both digital and analog—the signal only has two states, high and low, which makes it digital, yet at the same time, the time duration of the high pulses in the signal is an analog value, as it can have many distinct values. In this tutorial, I’ll first cover some of the basics of the theory behind PWM, and will then introduce you to PWM implementation on the Arduino!
Let’s turn to the simple example of an LED. If I wanted to dim the LED, I could simply reduce the voltage across it using a potentiometer or resistor voltage divider.
Alternatively, however, I could represent this lower voltage digitally by pulsing the LED on and off extremely quickly at a specified rate—the LED would appear to be dimmer because in a given time interval it is not on 100% of the time, yet it would appear to be still (not flashing) because of the rapidity of the pulsing. This is the idea of PWM. One can switch a signal rapidly so that it is on for a specific percentage of the time interval to give an “average voltage” effect. Note that there are quotes around average voltage because no actual voltage modulation occurs! PWM is extremely convenient in many situations because it is much simpler to implement than such a method of changing voltages through electronics.
Individuals who explore PWM signaling often encounter the term duty cycle. Duty Cycle is expressed as a percentage that indicates the proportion of a given period of time in which the PWM signal is high. This means that in a ten-second time interval, a PWM signal with a duty cycle of 20% is only on for two of those ten seconds. This does not mean, however, that the signal is high for the first two seconds and low for the remaining time. Instead, the two second time period during which the signal is high is distributed evenly over the ten seconds. This distribution depends on the modulating frequency of the PWM signal, the number of on-off cycles the signal undergoes in a second.
Here’s an illustration of duty cycles with a 5V digital signal.
Note that the percentage of a clock cycle spent in the high state is equal to the duty cycle percentage.
Now we can focus on PWM implementation on the Arduino! Let’s look at the LED example from above. By wiring the LED up to an analog out or PWM pin on the Arduino and calling the analogWrite function, we can control the brightness of the LED! That’s right! So-called “Analog” pins on the Arduino actually use PWM to send signals representing “voltages” between 0V and 5V.
On the hardware side, the only connection between the Arduino and the LED would be to an Analog Out or Digital/PWM pin and to Ground. Digital/PWM pins on the Arduino are indicated by “~” before their pin numbers. On an Arduino Uno, the Digital/PWM pins are 3,5,6,9,10, and 11.
Inside void loop(), we can then call the analogWrite method with a corresponding integer value between 0 and 255 to represent the brightness of the LED. This would mean that analogWrite(0) is a 0% duty cycle on the output signal (the LED is off), analogWrite(125) is a 50% duty cycle (the LED is half of its maximum brightness), and analogWrite(255) is a 100% duty cycle (the LED is at its maximum brightness).
The output signal is actually causing the LED to pulse at a very high frequency that makes individual pulses indiscernible. Therefore we do not see a flashing LED, but merely see it as dimmer or brighter when the duty cycle is modified. We can apply this concept to motor speed control as well. Here’s the setup for controlling the speed of a dc motor.
The PWM signal is transmitted from the Arduino’s Digital/PWM Pin 9 to the base pin of the transistor. The transistor switches at the same rate as the PWM signal does, thereby driving the motor at the duty cycle of the PWM signal! Just like the LED, the motor is actually switching on and off at thousands of time per second, but it appears and acts as if it is in continuous motion because it is switching at such a high rate.
The capacitor and diode in the motor-control circuit are necessary to assist in sudden on-to-off switching of the motor. When suddenly switched off, motors can generate an enormous back-voltage that can cause damage to other electronics. In conjunction, the diode and capacitor prevent any damaging voltage spikes.
Finally, it is important to note that the analogWrite function should not directly be used to control servos or electronic speed controllers (ESC) through PWM. This is because the frequency at which these devices expect PWM signals is much lower than the frequency of the analogWrite-generated PWM signal. Arduino provides a great library called Servo to control Servos and ESCs. We’ll cover the Servo library in a coming tutorial!
Courtesy to Fritzing and Arduino for the images used in this article.