Learning Goals 5 min
- Convert an
analogWritevalue (0–255) into its duty cycle as a percentage, and into the average voltage on the pin. - Calculate the period and frequency of a PWM signal — and explain why the Arduino's default 490 Hz looks steady to your eye but not to a fast camera.
- Predict how bright an LED will look at a given duty cycle, knowing that the eye sees brightness on a curve, not a line.
Warm-Up 10 min
Yesterday you typed analogWrite(LED, 128) and called it "half brightness". Today we ask which half.
Pencil puzzle
Imagine a pin switching cleanly between 0 V and 5 V. In every 1 ms window, the pin spends:
- 0.25 ms
HIGH(at 5 V), - 0.75 ms
LOW(at 0 V).
What's the average voltage across that 1 ms window?
Reveal
Total area under the curve = 0.25 ms × 5 V + 0.75 ms × 0 V = 1.25 mV·s. Divide by the window length (1 ms): average = 1.25 V. That's 25% of 5 V. The fraction of time at HIGH — 25% duty cycle — is exactly the multiplier on the supply voltage. That single formula is what today is about.
New Concept · The duty-cycle formulas 20 min
Formula 1 — analogWrite value → duty percentage
The analogWrite function takes an 8-bit value. 0 is always off, 255 is always on. Anything in between is a proportional duty cycle:
duty% = (value / 255) × 100Examples:
analogWrite value | Duty cycle | One sentence |
|---|---|---|
| 0 | 0% | Pin always at 0 V. |
| 64 | 25.1% | On a quarter of the time. |
| 128 | 50.2% | Equal on/off — the "halfway" setting. |
| 192 | 75.3% | On three quarters of the time. |
| 255 | 100% | Pin always at 5 V. |
Formula 2 — duty percentage → average voltage
The pin only ever swings between 0 V and 5 V (or 3.3 V if you're on a 3.3 V board). The average voltage over many cycles is just the duty cycle times the supply:
V_avg = duty% × V_supply
= (value / 255) × 5 V on a 5 V UNOanalogWrite | Duty | V_avg on a 5 V UNO |
|---|---|---|
| 0 | 0% | 0.00 V |
| 51 | 20% | 1.00 V |
| 128 | 50.2% | 2.51 V |
| 204 | 80% | 4.00 V |
| 255 | 100% | 5.00 V |
Formula 3 — period and frequency
The PWM signal repeats. Period (T) is the length of one complete on-then-off cycle. Frequency (f) is how many cycles happen per second. They're reciprocals:
f = 1 / T (Hz = cycles per second)
T = 1 / f (seconds per cycle)On most UNO pins the PWM frequency is about 490 Hz. So:
- One period T = 1 / 490 ≈ 2.04 ms.
- At 50% duty, the pin is
HIGHfor ~1.02 ms thenLOWfor ~1.02 ms. - At 25% duty, the pin is
HIGHfor ~0.51 ms thenLOWfor ~1.53 ms.
On D5 and D6 the frequency is roughly 980 Hz — twice as fast, period ~1.02 ms. That's a quirk of the AVR chip's timers and won't matter for LEDs, but it can matter for motors and audio.
Formula 4 (sneaky) — perceived brightness ≠ duty cycle
Your eye is more sensitive at low light than at high light — a real-world "volume curve" for vision. So an LED at 50% duty doesn't look half as bright as one at 100% — it looks closer to 70%. The technical name is gamma correction, with γ ≈ 2.2 for most displays:
perceived = (duty)^(1/2.2)
≈ (duty)^0.45So a duty cycle of 0.5 (50%) looks like roughly 0.50.45 ≈ 0.73 → about 73% perceived brightness. The full table:
| Duty | Perceived (γ = 2.2) | Why this matters |
|---|---|---|
| 10% | ~35% | A low-duty LED looks brighter than the maths predicts. Useful for night-lights. |
| 25% | ~54% | Halfway in perception happens at only a quarter of the duty. |
| 50% | ~73% | The classic "dim" setting actually looks pretty bright. |
| 75% | ~88% | The upper end of the duty range is a crowded zone — small steps barely show. |
| 100% | 100% | Anchor point. |
The takeaway: when you fade an LED in even analogWrite steps (0, 32, 64, ...), the fade looks fast at the start, slow at the end. To get a fade that looks smooth, the steps need to be small near zero and large near 255. We'll exploit this in L02-04.
Worked Example · Calculate, then check on the board 20 min
Step 1 — pick a target voltage
Goal: drive the pin to an average of 2.0 V. What analogWrite value do you need on a 5 V UNO?
Rearrange Formula 2 for value:
V_avg = (value / 255) × 5 V
value = (V_avg / 5) × 255
= (2 / 5) × 255 = 0.4 × 255 = 102So analogWrite(LED, 102) targets 2.0 V average. Round to the nearest whole number — 102.
Step 2 — write the sketch and check with a multimeter
// L02-03: target a specific average voltage
const int LED = 9;
void setup() {
pinMode(LED, OUTPUT);
analogWrite(LED, 102); // ~2 V average on 5 V UNO
}
void loop() { }Upload. Put your multimeter probes between pin 9 and GND on the breadboard, set to DC volts (200 V range or auto). The reading should be very close to 2.0 V — typically 1.95–2.05 V depending on the meter's averaging.
Step 3 — try the other classic targets
| Target V_avg | Compute value | Expected multimeter reading |
|---|---|---|
| 1.0 V | (1/5) × 255 = 51 | ~1.0 V |
| 2.5 V | (2.5/5) × 255 = 128 (rounded) | ~2.5 V |
| 3.3 V | (3.3/5) × 255 = 168 (rounded) | ~3.3 V |
| 4.0 V | (4/5) × 255 = 204 | ~4.0 V |
Real-world note
Your multimeter might be a tiny bit off (say, 0.95 V when you expected 1.00 V). That's usually the meter's input impedance or the PWM ripple averaging. Don't fight it — the maths is right.
Basic 7 min
Fill in the missing values. Show your working.
analogWrite | Duty % | V_avg (5 V UNO) |
|---|---|---|
| 26 | ____ | ____ |
| 153 | ____ | ____ |
| 230 | ____ | ____ |
Challenge 1 7 min
You want exactly 1.5 V average on a 3.3 V board (e.g. Nano 33 BLE). What analogWrite value should you use?
Challenge 2 6 min
The PWM frequency on D9 is 490 Hz. At analogWrite(D9, 64), how many microseconds is the pin HIGH during each cycle? And how many is it LOW?
Challenge 3 · The phantom voltmeter 15 min
Without uploading or using a multimeter, predict the steady multimeter reading (DC volts, 5 V UNO) for the following sketch.
const int LED = 9;
void setup() {
pinMode(LED, OUTPUT);
}
void loop() {
analogWrite(LED, 85);
delay(2000);
analogWrite(LED, 170);
delay(2000);
}Predict:
- What does the multimeter read during the first 2-second window?
- What does it read during the second 2-second window?
- If you set the meter to average over 4 seconds, what overall reading would you expect?
Recap 5 min
PWM is a percentage game. analogWrite value over 255 gives you the duty as a fraction; multiply by your supply voltage to get the average; multiply by 100 to read it as a percentage. The period is the inverse of the frequency, so 490 Hz means each cycle lasts roughly 2 ms. And your eye lies a bit — perceived brightness follows a γ ≈ 2.2 curve, which is why dim LEDs look brighter than the maths suggests. Tomorrow we put all this to work with a smooth LED fade.
- Period (T)
- The duration of one complete cycle of a repeating signal. Measured in seconds, milliseconds or microseconds.
- Frequency (f)
- How many cycles happen per second, measured in Hertz (Hz).
f = 1 / T. - Average voltage
- Duty fraction × supply voltage. For an UNO on 5 V: V_avg = (analogWrite_value / 255) × 5.
- Gamma correction (γ ≈ 2.2)
- The curve that maps linear duty cycle to perceived brightness. Half-duty looks like ~73% bright, not 50%.
Extra Mission 5 min
Part 1 — Design a level gauge light
Many devices show a level with one light — fuel left, battery charge, time left in a game. Pick one. On paper, design a single LED that shows that level by its average voltage.
Your design must include:
- A name and a one-sentence job for the device.
- At least four levels, for example full, half, low and empty.
- A table with the duty %,
analogWritevalue and average voltage for each level. UseV_avg = (value / 255) × 5. - The PWM pin and resistor you will use.
Part 2 — Make it
Write a sketch that shows each of your levels for 2 seconds in turn. For each level, print the analogWrite value and the average voltage to two decimal places. Work the voltage out in code with a float, not by hand.
Bring back next class: the uploaded sketch, a Serial Monitor screenshot and your table. The printed voltages should match your table.