Lesson 4 of 6 · 16 min
PWM: faking analog output
A digital pin has only two voltages: 0 V and 5 V. There is no 2.5 V setting, and the Uno has no real analog output at all. Yet you can dim an LED smoothly, set a motor to half speed and move a servo to a precise angle. The trick is to switch the pin on and off so fast that the load only notices the average. This is pulse width modulation, PWM, and it is the single most useful technique in robotics output.
The idea: average, not level
Recall from lesson 2 that blinking faster than about 20 Hz looks like a steady glow. Now take that further: keep the switching frequency fixed and change how long the pin stays high within each cycle. That fraction is the duty cycle:
duty = t_high / T
where T is the period of one full cycle. The average voltage the load sees is:
V_avg = duty x V_supply
At 5 V:
| Duty cycle | Pin is HIGH for | Average voltage |
|---|---|---|
| 0% | never | 0 V |
| 25% | one quarter of each cycle | 1.25 V |
| 50% | half | 2.5 V |
| 75% | three quarters | 3.75 V |
| 100% | always | 5 V |
Try it yourself. Move the slider and watch how the pulse width changes while the period stays the same.
An LED looks half bright at 50% duty because your eye and the LED's light output average the flashes. A motor does something similar: its windings have inductance, which resists rapid changes of current, so the motor's speed follows the average power rather than each individual pulse.
analogWrite and the 0 to 255 scale
On the Uno, the function is named analogWrite, which is misleading because the output is still digital. It takes a value from 0 to 255, an 8-bit number:
duty = value / 255
So analogWrite(pin, 64) gives 64 / 255 = 25.1% duty and an average of about 1.25 V. analogWrite(pin, 128) gives about 50%, and analogWrite(pin, 255) is permanently HIGH.
Only some pins have the hardware timers needed for PWM. On the Uno they are marked with a tilde on the board:
| Pins | Timer | Frequency |
|---|---|---|
| 5, 6 | Timer 0 | about 980 Hz |
| 9, 10 | Timer 1 | about 490 Hz |
| 3, 11 | Timer 2 | about 490 Hz |
Calling analogWrite on any other pin, such as 13, just writes LOW for values below 128 and HIGH for 128 or more. At 490 Hz, one period is T = 1 / 490 Hz = 2.04 ms, which is far too fast for the eye to see flicker.
Blue pins: analog inputs. Orange pins: digital I/O.
Dimming and fading an LED
Connect an LED with a 220 Ω resistor to pin 9. This sketch fades it up and down:
const uint8_t LED_PIN = 9; // pin 9 supports PWM
int brightness = 0; // 0 to 255
int step = 5; // change per update
void setup() {
pinMode(LED_PIN, OUTPUT);
}
void loop() {
analogWrite(LED_PIN, brightness); // set the duty cycle
brightness += step; // move toward the other end
if (brightness <= 0 || brightness >= 255) {
step = -step; // reverse direction at the limits
}
delay(30); // 51 steps x 30 ms is about 1.5 s per ramp
}
The ramp takes 255 / 5 = 51 steps and each lasts 30 ms, so a full fade takes about 51 x 30 ms = 1.53 s. Make the step smaller or the delay shorter and the fade becomes smoother or faster.
There is one surprise. Your eye does not perceive brightness linearly: 50% duty looks much brighter than half of full brightness. For a natural-looking fade, many people square the value, for example analogWrite(LED_PIN, (brightness * brightness) / 255). Try both versions and compare.
Why a motor cannot hang on a pin
PWM is also how you control motor speed, but you must not connect a motor straight to an Uno pin. Do the maths. A pin supplies at most 20 mA, so its power is:
P_pin = 5 V x 0.020 A = 0.1 W
A small 6 V hobby motor drawing 300 mA needs:
P_motor = 6 V x 0.3 A = 1.8 W
That is 18 times more than the pin can deliver, and the motor's stall current can be several times higher. The pin would overheat and the chip could be damaged for good. A motor is also an inductor, and when current is switched off it generates a high-voltage spike that can travel back into the chip.
The solution is to let the pin control a switch that carries the load current:
- The Arduino PWM pin drives the base of an NPN transistor (such as a 2N2222) or the gate of a logic-level MOSFET.
- The transistor connects the motor to its own supply and carries the full current.
- A flyback diode (such as 1N4001) across the motor, cathode to the positive side, absorbs the spike.
For the transistor, assume a safe gain of 50. Base current is 300 mA / 50 = 6 mA, so the base resistor is (5 V - 0.7 V) / 0.006 A = 717 Ω, and the next standard value down, 680 Ω, is a good choice. The pin now supplies only 6 mA, safely within its limits.
Check yourself
You call analogWrite(9, 191). What is the approximate duty cycle and average voltage on a 5 V Uno?
Check yourself
Why should a 300 mA motor be driven through a transistor instead of directly from a PWM pin?