Two ways to notice a button press
Polling and interrupts are the two ways a chip finds out that something has happened, such as a button being pressed. Polling means looking again and again. An interrupt means being told.
Which one you choose decides how much of the chip's time is wasted, and whether one press is counted as one or as three.
By the end of this lesson
Note
I can explain polling and interrupts.
Key words
| Word | What it means |
|---|---|
| Polling | checking an input again and again |
| Interrupt | a signal that makes the chip stop and run a handler |
| Handler | the function the chip runs when an interrupt fires |
| Rising edge | the moment a pin goes from low to high |
| Bounce | the flicker a real button makes as it closes |
| Debounce | ignoring the extra edges that bounce makes |
The cells students fill in are left blank in this preview.
Polling asks the pin on every pass
A program that polls reads the button pin over and over in a loop. If the pin is high, the button is down.
To find a press, not just a held button, the program must remember the last reading. That remembered value is the state. A press is the moment the reading goes from 0 to 1, a rising edge.
Poll a bouncing button for 12 ticks
docker exec jupyter python3 steps/poll.pyShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
One real press can look like two
The script feeds the chip the signal a real button makes: 0 0 1 0 1 1 1 1 1 1 0 0. The button closes, flickers open for one tick, then closes and stays closed. This flicker is bounce.
The polling loop sees a rising edge at tick 2 and again at tick 4. It prints "yes" twice and ends with "one real press, but the loop counted 2".
Worked example: where the edges are
| Tick | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|---|---|
| Pin reading | 0 | 0 | 1 | 0 | 1 | 1 | 1 |
| Last reading | 0 | 0 | 0 | 1 | 0 | 1 | 1 |
| Rising edge? | no | no | yes | no | yes | no | no |
The cells students fill in are left blank in this preview.
An interrupt tells the chip for you
With an interrupt the chip watches the pin for you. When the pin goes from low to high, it sets a bit called the interrupt flag, IFR. If interrupts are switched on, the chip stops what it was doing and calls your handler.
The handler is a short function. When it finishes, the main program carries on. The program no longer spends its time asking.
Handle the same press with an interrupt
docker exec jupyter python3 steps/interrupt.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 an interrupt cures bounce. It does not. The chip calls the handler for every rising edge, so one press still calls it twice. An interrupt only means the chip need not keep asking. The bounce is still in the signal, so your code must deal with it.
Debounce by waiting after the first edge
The script then keeps a call only if it came more than 3 ticks after the last call it kept. The edges at ticks 2 and 4 are 2 ticks apart, so the second is dropped. It prints "calls kept after waiting out the bounce: 1".
The length of the wait is a choice. Too short and bounce gets through. Too long and a quick double press is lost.
Debounce a list of edges
edges = [3, 5, 12, 14, 15] # ticks where the pin rose
wait = 3 # change this to 1, then press Run
kept = []
for tick in edges:
if len(kept) == 0:
kept.append(tick)
elif tick - kept[-1] > wait:
kept.append(tick)
print(kept)