In this article, learn how to use interrupts in Raspberry Pi Pico. A pushbutton will be used to explain how interrupts work.
We can interface a push button using either Polling or Interrupt. Here, you can learn the difference between the two methods and which one to use. The code in this article is written in MicroPython.

The Raspberry Pi Pico & Pico W boards have 26 General Purpose Input/Output (GPIO) pins that can be accessed using the header pins All GPIO pins of Raspberry Pi Pico can be configured as either input or output. All GPIO pins can also be configured as external interrupts.
Polling vs. Interrupts
Polling and interrupts are the two methods used to interface external switches such as push-buttons, keypads, numpad, etc. to a microcontroller or microprocessor.
Polling is used when the application is not time-sensitive. Interrupts are used when a device needs the attention of a microcontroller instantly.
| Polling | Interrupt |
| Polling is when the CPU executes code sequentially to check if any change in state has occurred. | In case of Interrupts, a device or a register notifies the CPU that it needs immediate attention. |
| CPU takes care of Polling. | An interrupt handler handles interrupts. |
| Polling occurs at regular intervals due to the sequential execution of code. | Interrupts can occur at any time. |
Interrupts are handled by parts of software called Interrupt Service Routine(ISR). When an interrupt occurs, the CPU starts executing code within this routine. When the task in the routine is completed, the processor continues executing code from where it left off.

Prerequisites For This Tutorial
- A Raspberry Pi Pico development board
- Push button(such as a momentary tactile switch)
- Connecting wires and breadboard
Your Raspberry Pi Pico needs to be preloaded with a MicroPython UF2 file to program it in MicroPython. You can read our getting started guide for Raspberry Pi Pico where we show all the steps required to start programming Raspberry Pi Pico in MicroPython.
Read Pins using Polling in Raspberry Pi Pico
Let us first learn the polling method of reading an input pin state. If you are familiar with polling – jump to the interrupts section.
Connect a push-button to your Pico as shown in the diagram below.


Push buttons or tactile switches generally act as input devices. A push-button connected to the positive supply voltage of a microcontroller will be read as logical high (1) and a button connected to the ground will be read as logical low (0).
Raspberry Pi Pico has 26 easily accessible GPIOs explained in our in-depth article Raspberry Pi Pico Pinout Guide. You can use any of these GPIO pins to connect push-buttons. Here is the pin diagram of Raspberry Pi Pico W for reference.

I will explain a simple MicroPython script to detect if an input pin is logical high or low.
The steps to upload code are explained here using Thonny IDE. You can also use any other IDE such as the uPyCraft IDE.
With the connections done as shown in the schematic above, connect Pico to your computer. Open Thonny IDE and set the interpreter to use MicroPython on Raspberry Pi Pico.
Create a new file (go toFile>New).
Paste the following script:
from machine import Pin
counter=0
pin = Pin(5, Pin.IN, Pin.PULL_UP)
while True:
if pin.value()==0:
print("Button Pressed")
counter+=1
print("Count={}".format(counter))Code language: Python (python)
Click on File>Save as and select the save location as Raspberry Pi Pico.

Name the code file as main.py.

Run the code by clicking the Run icon or by pressing the F5 key.

Now, when you press the push-button, you should see output in the shell of Thonny IDE as shown below:

Alternatively, if you wish to detect a button press when the button is logically high instead of low, use PULL_DOWN instead of PULL_UP and modify your code as shown below:
from machine import Pin
counter=0
pin = Pin(5, Pin.IN, Pin.PULL_DOWN)
while True:
if pin.value() is 1:
counter+=1
print("Button Pressed")
print("Count={}".format(counter))Code language: Python (python)
Code Explained:
- We import the
Pinclass from themachinemodule which is required to interact with the GPIO pins. Then we create a variable calledcounterto keep count of how many times the switch has been pressed.
from machine import Pin
counter=0Code language: JavaScript (javascript)
- An object
pinis created which takes 3 arguments. We designate GPIO 5 as an input withPULL_UPenabled. Pico can pull a pin to the positive voltage rail with an internal resistor. We need a pullup resistor because without it, a pin’s state might be noisy as it will be in a floating state.
pin = Pin(5, Pin.IN, Pin.PULL_UP)Code language: Python (python)
- Inside the while loop, we see if
pin.value()is equal to 0, which denotes that the pin has been connected to the ground(i.e. the pushbutton is pressed). If a button press is detected, we increment thecountervariable and print the value of the counter.
if pin.value() is 1:
counter+=1
print("Button Pressed")
print("Count={}".format(counter))Code language: Python (python)
Also read: Arduino vs MicroPython vs CircuitPython: Which One Will You Choose?
Debouncing a Pin in Raspberry Pi Pico
Did you notice any shortcomings in the script we wrote above? A single button press may increment the counter by many counts. This is due to the nature of mechanical contacts in a button and is called Bouncing.
Debouncing is a process of eliminating bouncing by using software or hardware. For example, a resistor-capacitor combination can be used for debouncing a switch. In software, the time elapsed between two consecutive button presses is measured, and if multiple inputs occur within a certain time interval, only one input is registered.
To implement debouncing, we need to modify our script so that push-button presses are detected only when there is a small amount of delay in between consecutive presses. Clicking a push-button rapidlywill not be registered as a valid input. For this, we shall use the time module in MicroPython to detect the time between button presses.
The time module contains the function time.ticks_ms() which is described as “Returns an increasing millisecond counter with an arbitrary reference point, that wraps around after some value.”
So the function returns a value of time (in milliseconds) that increments periodically, and we can use it to measure the time interval between two events.
Upload this modified script and save the file on Raspberry Pi Pico with a ‘.py’ filename extension:
from machine import Pin
import time
counter=0
debounce_time=0
pin = Pin(5, Pin.IN, Pin.PULL_UP)
while True:
if ((pin.value() is 0) and (time.ticks_ms()-debounce_time) > 300):
counter+=1
debounce_time=time.ticks_ms()
print("Button Pressed")
print("Count={}".format(counter))Code language: Python (python)
We import the time module and create a variable called debounce_time. Then, we check if the time elapsed since the last button press is more than 300 milliseconds, using (time.ticks_ms()-debounce_time) > 300). If this condition is satisfied, then we increment the button press counter and set the debounce_time to the current value returned by time.ticks_ms(). This is very similar to using the millis() function in Arduino IDE.
External Interrupts in Raspberry Pi Pico
All GPIO pins in Raspberry Pi Pico support interrupts. The interrupts can be classified into three types:
- Level High: An interrupt occurs when a pin is HIGH or at logic 1.
- Level Low: An interrupt occurs when a pin is LOW or at logic 0.
- Rising Edge: Interrupt occurs when a pin transitions from a LOW to HIGH.
- Falling Edge: Interrupt occurs when a pin transitions from HIGH to LOW.

The level interrupts in RPi Pico do not latch, i.e. the interrupt becomes inactive as soon the GPIO changes its state from HIGH to LOW or vice versa.
Also read: Raspberry Pi Pico Serial Communication Example(MicroPython)
Using Push-Buttons to Trigger Interrupts
Let us now try to interface a pushbutton using an interrupt. For this example, we shall use the Falling Edge(or Edge Low) of a pin voltage to trigger an interrupt. The connections will be the same as we used in the previous example for Polling a button input i.e. connect a pushbutton between GPIO5 and GND pin.
- In Thonny IDE, create a new project and upload the following interrupt example script to your Pi Pico.
from machine import Pin
pin = Pin(5,Pin.IN,Pin.PULL_UP)
def callback(pin):
print("Interrupt has occured")
pin.irq(trigger=Pin.IRQ_RISING, handler=callback)Code language: Python (python)
- Save and run the script.
When the script runs, you must see the line “Interrupt has occurred” displayed in your Thonny shell window when the pushbutton is pressed.

You might notice that the line “Interrupt has occurred” is printed multiple times with just a single button press. This is similar to the button-bouncing issue we discussed earlier in this article. We shall deal with this issue shortly below.
External Interrupt Code Explained
We first import the Pin class.
from machine import PinCode language: Python (python)
GPIO 5 is set as an input with internal PULL_UP enabled.
pin = Pin(5,Pin.IN,Pin.PULL_UP)
Next, we define a function called callback() to handle interrupts. The code inside this function should not perform any complex task, as it needs to hand over CPU usage to the main program quickly.
def callback(pin):
print("Interrupt has occured")Code language: Python (python)
To attach the interrupt to the pin, we use the irq() function.
pin.irq(trigger=Pin.IRQ_FALLING, handler=callback)
This function takes two arguments :
1. trigger : trigger can be of the following types-
- Pin.IRQ_FALLING– interrupt on falling edge.
- Pin.IRQ_RISING– interrupt on rising edge.
- Pin.IRQ_LOW_LEVEL – interrupt on LOW level.(Not supported in MicroPython for Pico at the time of publishing this article.)
- Pin.IRQ_HIGH_LEVEL
-interrupt on HIGH level.(Not supported in MicroPython for Pico at the time of publishing this article.) - Pin.IRQ_FALLING | Pin.IRQ_RISING – interrupt on both the rising edge and the falling edge.
2. handler : handler specifies the function that will be called when an interrupt occurs.
Debouncing Interrupts & Controlling Output Pins
Debouncing is required even when using interrupts. Consider the example of edge-triggered interrupts (like Pin.IRQ_FALLING) that fire when a signal changes state. But a mechanical button doesn’t change state cleanly. It often bounces between HIGH and LOW several times within a few milliseconds before settling. Multiple falling edges can happen due to bouncing. Each of those can trigger the interrupt, causing your callback to run multiple times even if you only tapped the button once.
In the following example let us toggle the onboard LED of the Raspberry Pi Pico on the press of a push-button and use debouncing on the interrupt pin.
from machine import Pin
import time
# Variables for debounce timing and interrupt handling
interrupt_flag = 0
debounce_time = 0
# Set up button pin with pull-up resistor
button = Pin(5, Pin.IN, Pin.PULL_UP)
# Set up onboard LED on Raspberry Pi Pico
led = Pin("LED", Pin.OUT)
# Interrupt callback function
def callback(pin):
global interrupt_flag, debounce_time
current_time = time.ticks_ms()
# Debounce check- only proceeds if 500ms has passed since the last trigger
if time.ticks_diff(current_time, debounce_time) > 500:
interrupt_flag = 1 # Set flag to handle in the main loop
debounce_time = current_time # Update last debounce time
# Attach interrupt to button (falling edge = button press)
button.irq(trigger=Pin.IRQ_FALLING, handler=callback)
# Main loop
while True:
if interrupt_flag:
print("Button press detected!")
led.toggle() # Toggle LED state
interrupt_flag = 0 # Reset flag
time.sleep(0.01) # Small delay to avoid busy-waiting
Code language: Python (python)
Now, when the pushbutton is pressed, the onboard LED must change between ON and OFF states.
Polling or Interrupt? Which One Should You Use?
If you are interfacing external devices that are time-sensitive, you should use interrupts. If your program is simple, you can use polling to interface buttons. Some microcontrollers have few external interrupt-compatible pins. If you have to interface many buttons, such as a keypad, you sometimes have to opt for polling instead of using interrupts.
I hope you found this article on using external interrupts in Raspberry Pi Pico to be useful. Please share your thoughts in the comments below. Thank you for reading.
Also read:
Leave a Reply