Robotics · Microcontrollers · Grade 8
PWM: brightness and sound
analogWrite(9, 64) — why does the LED glow at 25 % and what tune does the buzzer play?
The situation
The front light of a robot car should not be abrupt but fade smoothly on and off — and it should also sound a signal. But an Arduino pin knows only two states: 0 V or 5 V. How do we get “half” brightness? If you write analogWrite(9, 64), the LED glows at a quarter of its brightness — but on the oscilloscope there is no “quarter” voltage on the pin: only rapid switching on and off. Why does the eye take this for smooth light? Why does brightness that rises in equal steps from 0 to 255 not look even to the eye? And where does the 440 in tone(8, 440) come from?
Topic
PWM: analogWrite, brightness and sound. An LED fades smoothly, a buzzer plays a tune: duty cycle and frequency
Key ideas
- Duty cycle
- The eye and gamma
- tone() — frequency
Formulas
PWM (pulse-width modulation): `analogWrite(pin, v)` switches the pin on and off at frequency , HIGH for the fraction of the period. Uno: on pin 9 the frequency is 490 Hz → = 2.04 ms; = 64 → = 25 %, = 0.51 ms.
The average voltage and current are proportional to the duty cycle. The light of an LED is proportional to the average current — with 220 Ω, ≈ 12.7 mA.
The eye (CIE 1976 ): perceived lightness (0–100) is close to the cube root of the light (0–1). = 10 % → ≈ 38, = 50 % → ≈ 76: one tenth of the light looks to the eye like more than a third.
Gamma correction: to make the steps look equal to the eye we raise to a power — small steps at the start, large ones at the end.
Notes are frequencies: La (A4) = 440 Hz, each semitone is ≈ 1.0595 times higher. Do (C4) = 262, Re 294, Mi 330, Fa 349, Sol 392, La 440, Si 494, Do (C5) 523 Hz. `tone(pin, f)` gives a wave of that frequency with a 50 % duty cycle.
Theory
PWM: an “average” from two states
A microcontroller pin is digital: 0 V or 5 V, nothing in between. But `analogWrite(pin, v)` switches the pin on and off hundreds of times a second: = 255 — on all the time, 128 — half the time, 64 — a quarter of the time. This is PWM, pulse-width modulation; the fraction of time spent on, , is called the duty cycle. For the circuit it is an “average” voltage of volts: the average current of the LED and its brightness are proportional to . The eye does not notice flicker at 490 Hz — it “collects” light over roughly 1/50 s: flicker faster than 50–60 Hz looks like steady light.
Which pins, which frequency
On the Uno, PWM exists only on the pins marked ~: 3, 5, 6, 9, 10, 11 — they are driven by three timers: Timer0 — 5 and 6 (≈ 980 Hz; this timer also counts `millis()`), Timer1 — 9 and 10 (490 Hz), Timer2 — 3 and 11 (490 Hz). The frequency does not affect the brightness — only matters; at 980 Hz the period is half as long. On other pins (13 too) `analogWrite` is a plain switch: → LOW, → HIGH. = 0 and = 255 on any pin give exactly LOW / HIGH — like `digitalWrite`.
The eye is not linear
In the Fade program grows evenly from 0 to 255, but the LED brightens very fast at the start and then hardly changes. The reason is the eye: perception is proportional not to the light itself but roughly to its cube root (the CIE 1976 formula , on which colour science and screens are based). 10 % of the light looks to the eye like ≈ 38 %, 50 % like ≈ 76 %. To make the steps look equal we need gamma correction: , ≈ 2.2–3 — small steps at the start, large ones at the end. Every screen and every LED lamp “dimmer” has such a table.
Reading the oscilloscope trace
The oscilloscope draws the pin voltage against time: 1 ms/div — 10 ms across the screen. At 490 Hz the period ≈ 2.04 ms — about 5 periods on the screen; at 980 Hz about 10. The width of the on pulse is : 0.51 ms at = 64, 1.53 ms at = 191. The amplitude is always 5 V — PWM changes not the voltage but the time. This is how PWM can be told apart from a true analog voltage (a DAC): the Uno has no DAC.
tone(): sound is PWM too
A passive piezo buzzer (a piezo disc) does not sound by itself — it has to be given vibrations: `tone(pin, f)` switches the pin on and off at frequency with a 50 % duty cycle (an active buzzer, in contrast, squeals by itself at one fixed tone when given 5 V). In music every note is a frequency: La (A4) 440 Hz, an octave — twice as high, a semitone — times. `tone(pin, f, ms)` stops by itself after the given time and does not hold up the program; `noTone(pin)` switches it off. On the Uno only one tone can play at a time, and it takes over Timer2 — PWM on pins 3 and 11 stops meanwhile. A piezo buzzer draws almost no current; a 16 Ω magnetic buzzer, however, cannot be connected straight to a pin: the current is ≈ 120 mA — three times the 40 mA limit, and the chip burns out (a transistor or 100 Ω is needed).
About the model
The oscilloscope trace is drawn ideally from the duty cycle and the frequency (sharp edges; on a real pin the edges take a few nanoseconds because of ≈ 25 Ω and capacitance). The light of the LED is taken as proportional to the average current (which is true in the working range of an LED); the “seen by the eye” value is CIE : the eye is much more complicated (ambient light, adaptation), but the cube root is a good first approximation. The sound is a square wave from the computer speaker, at a low volume, and only if you switch it on; a real piezo buzzer sounds much louder, around 2–4 kHz (resonance). The heating of the chip is simplified as in `arduinoblink`.
Did you know?
- The piezoelectric effect was discovered in 1880 by the brothers Jacques and Pierre Curie: if you squeeze a quartz crystal, a charge appears in it, and if you apply a voltage, it vibrates. The piezo disc in a buzzer, quartz watches and ultrasonic sensors all work on this effect.
- The note A at 440 Hz is the international standard: ISO adopted it as a recommendation in 1955, and the current ISO 16 standard dates from 1975. Before that orchestras were tuned differently — 435 Hz in 19th-century Paris, in some places even higher than 450 Hz.
Inside the experiment
A real board in a hand-inked isometric drawing: turn it, place the parts, wire the circuit, write and upload the code — current and voltage are computed at once, and a wrong connection burns a part. Inside are missions, theory, a quiz and a guided tour.
More experiments in this section
- Arduino Uno: the first program — Grade 7
- Button and digital input — Grade 7
- Analogue input and the Serial Monitor — Grade 7
- millis() and multitasking — Grade 8