How a chip dims a light
A GPIO pin is a metal leg of a chip that a program can set high or low. PWM (pulse width modulation) switches a pin on and off so fast that a light looks dimmer. With a timer and one number you can control how bright a light is, or how fast a motor turns.
A phone screen does this to dim its backlight. The light is only ever fully on or fully off.
By the end of this lesson
Note
I can drive a pin on a schedule.
Key words
| Word | What it means | Example |
|---|---|---|
| Pin | a metal leg of the chip, high (1) or low (0) | |
| GPIO | a general purpose input or output pin | |
| Timer | a counter that goes up by one on every tick | |
| Period | how many ticks the timer counts before it starts again | 16 |
| PWM | pulse width modulation: a pin switched on and off by a timer | |
| Duty cycle | the share of each period the pin is on |
The cells students fill in are left blank in this preview.
A DDR bit makes a pin an output
Each pin is either an output, which the chip drives, or an input, which the outside world drives. Which one is decided by one bit in a register called DDR, the data direction register.
A 1 in bit 0 of DDR makes pin 0 an output. Then bit 0 of PORT says whether that pin is high or low. The register PIN reads the level the pin really has.
Worked example: three registers, one pin
| Register | Job | For pin 0 |
|---|---|---|
| DDR | Chooses output (1) or input (0) | Bit 0 = 1, so an output |
| PORT | The level an output pin is told to have | Bit 0 = 1, so high |
| PIN | The level the pin has now | Bit 0 reads 1 |
The cells students fill in are left blank in this preview.
Drive pin 0 and blink it
docker exec jupyter python3 steps/pins.pyShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
A blink toggles a bit each tick
The script makes pin 0 an output, drives it high and shows DDR as 0b00000001 and PIN as 0b00000001. Then it toggles bit 0 of PORT once for each of eight ticks.
A tick is one step of the chip's clock. The script prints # for a tick where the pin was high and . where it was low, so you see #.#.#.#..
A timer counts ticks and starts again
A chip has no clock on a wall. It has a timer: a register that goes up by one on each tick. In this lab the timer is TCNT.
It counts from 0 to 15 and then goes back to 0. So one period is 16 ticks. A second register, OCR, holds a number to compare against. The register TCCR switches the timer and PWM on.
PWM is on for part of a period
In PWM mode the pin is high while the timer is below OCR and low for the rest of the period. A bigger OCR means the pin is on for longer.
The duty cycle is the number of ticks on, divided by the period, as a percentage. With a period of 16 and OCR of 4, the pin is on for 4 ticks of 16, which is 25 percent.
Worked example: three compare values, period 16
| OCR | Ticks on | Ticks off | Duty cycle |
|---|---|---|---|
| 4 | 4 | 12 | 25 percent |
| 8 | 8 | 8 | 50 percent |
| 12 | 12 | 4 | 75 percent |
The cells students fill in are left blank in this preview.
Print one PWM period three times
docker exec jupyter python3 steps/pwm.pyShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
A common mistake
Warning
Many people think a PWM pin at 50 percent sends out half the voltage. It does not. The pin is fully on for half the time and fully off for the rest. A light or a motor reacts slowly, so it follows the average. This chip is a simulator: a real chip has its own timer registers.
Work out a duty cycle
period = 16
compare = 4 # change this to 10, then press Run
levels = ""
for tick in range(period):
if tick < compare:
levels = levels + "#"
else:
levels = levels + "."
print(levels, levels.count("#") * 100 // period, "percent")