In the Button exercise, we used the "Wait for button press" block to detect when the button is pressed. This is fine for a simple project when there's only one input to detect.
But, while the program is running "Wait for button press," it cannot detect any other inputs.
That's a big problem if there are other things your program needs to do while also responding to a button press. Robots often need to monitor many sensors at the same time and need to not miss any of the events.
Suppose you wanted to detect when either of two buttons are pressed.
Your micropython code might do something like this:
However, if a button is pressed and released while the program isn't checking "btn_a.value() == 1",
the button press won't be detected.
The problem is worse if you're trying to detect an event from a sensor that happens very quickly.
btn_a = Pin(14, Pin.IN, Pin.PULL_DOWN)
btn_b = Pin(15, Pin.IN, Pin.PULL_DOWN)
while True:
# Check Button A
if btn_a.value() == 1:
print("Button A pressed!")
# Check Button B
if btn_b.value() == 1:
print("Button B pressed!")
The Raspberry Pi Pico, like most microcontrollers, includes capabilities that can be configured to detect changes on input pins while busily running your program. We call these "interrupts" because when the input pins change to a specific state, the main program is temporarily interrupted while code that handles (responds) to the event runs. Micropython has extensive support for interrupts -- see the documentation for "Interrupt related functions."
Here is an example program. Note that while the program is sleep-ing the hardware event is not missed!
from XRPLib.defaults import *
from machine import Pin
import time
# State variable to track if the interrupt occurred
interrupt_triggered = False
# Define the pin connected to your button or sensor
interrupt_pin = Pin(7, Pin.IN, Pin.PULL_UP)
# Define the interrupt handler (Callback)
def handle_interrupt(pin):
global interrupt_triggered
interrupt_triggered = True # Signal the main loop to act
# Attach the IRQ (Interrut Request) to trigger when the inpput pin voltage falls to GND
interrupt_pin.irq(trigger=Pin.IRQ_FALLING, handler=handle_interrupt)
# Main loop
while True:
if interrupt_triggered:
print("Interupt!")
# Reset the flag so it can be triggered again
interrupt_triggered = False
print("Sleeping ...")
time.sleep(0.5)