There are several things going on in your code. I suspect that what's really causing the problem is that you need to exit the interrupt handler before another interrupt callback can be triggered...but there is also a confusing mix of callback-based handlers and the GPIO.event_detected method.

I think you can simplify things by performing less manipulation of your interrupt configuration. Just have a state variable that starts at 0, increment it to 1 on the first interrupt, so the next time the interrupt method is called you know it's the second interrupt. No need to try setting multiple handlers like that.

Keeping in mind that I don't actually know what you're trying to do...I imagine something like this:

import RPi.GPIO as GPIO
import time

state = 0

GPIO.setmode(GPIO.BCM)
GPIO.setup(26, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(19, GPIO.IN, pull_up_down=GPIO.PUD_UP)


def interrupt_handler(channel):
    global state

    print("interrupt handler")

    if channel == 19:
        if state == 1:
            state = 0
            print("state reset by event on pin 19")
    elif channel == 26:
        if state == 0:
            state = 1
            print("state set by event on pin 26")


GPIO.add_event_detect(26, GPIO.RISING,
                      callback=interrupt_handler,
                      bouncetime=200)

GPIO.add_event_detect(19, GPIO.RISING,
                      callback=interrupt_handler,
                      bouncetime=200)


while (True):
    time.sleep(0)
Answer from larsks on Stack Overflow
Top answer
1 of 2
2

There are several things going on in your code. I suspect that what's really causing the problem is that you need to exit the interrupt handler before another interrupt callback can be triggered...but there is also a confusing mix of callback-based handlers and the GPIO.event_detected method.

I think you can simplify things by performing less manipulation of your interrupt configuration. Just have a state variable that starts at 0, increment it to 1 on the first interrupt, so the next time the interrupt method is called you know it's the second interrupt. No need to try setting multiple handlers like that.

Keeping in mind that I don't actually know what you're trying to do...I imagine something like this:

import RPi.GPIO as GPIO
import time

state = 0

GPIO.setmode(GPIO.BCM)
GPIO.setup(26, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(19, GPIO.IN, pull_up_down=GPIO.PUD_UP)


def interrupt_handler(channel):
    global state

    print("interrupt handler")

    if channel == 19:
        if state == 1:
            state = 0
            print("state reset by event on pin 19")
    elif channel == 26:
        if state == 0:
            state = 1
            print("state set by event on pin 26")


GPIO.add_event_detect(26, GPIO.RISING,
                      callback=interrupt_handler,
                      bouncetime=200)

GPIO.add_event_detect(19, GPIO.RISING,
                      callback=interrupt_handler,
                      bouncetime=200)


while (True):
    time.sleep(0)
2 of 2
0

That sleep(0) just causes the process to idle there while waiting for switch interrupts. Since nothing in there programmatically ends the process, doing a Ctl-C will stop it.

🌐
RasPi.TV
raspi.tv › 2013 › how-to-use-interrupts-with-python-on-the-raspberry-pi-and-rpi-gpio-part-3
How to use interrupts with Python on the Raspberry Pi and RPi.GPIO – part 3
June 22, 2015 - Multiple threaded callback interrupts in Python We’ve been learning about interrupts this week because of the brand new interrupt capabilities of RPi.GPIO. We covered a simple “wait for…
Discussions

WiringPi: using interrupts with Python - Raspberry Pi Stack Exchange
I want my RaspberryPi to perform some actions when the light in a room is switched on or off. To do so, I connected a photocell to the GPIO pins. Previously, I used some python 3 program that quer... More on raspberrypi.stackexchange.com
🌐 raspberrypi.stackexchange.com
June 28, 2015
Interrupt for python - Raspberry Pi Forums
How exactly interrupt works in raspberry If you can send me the example of it ... Interrupts work on the Pi in the same way they work on any Linux machine. Linux handles interrupts. Linux provides a method to request to be told when an interrupt happens. How you are told depends on the programming language. The Python ... More on raspberrypi.org
🌐 raspberrypi.org
September 29, 2017
python - Fastest Hardware Interrupt software? - Raspberry Pi Stack Exchange
I'm wiring my Raspberry pi to a USdigital encoder , especifically this model "H6BM-1000-500-IE-S-H" , it has 1000 signals per revolution , I've followed the tutorial on http://raspi.tv/2013/how-... More on raspberrypi.stackexchange.com
🌐 raspberrypi.stackexchange.com
April 22, 2016
gpio - Does Python Get Interrupted When Running on PI? - Raspberry Pi Stack Exchange
I have seen seen in many places that the Raspberry Pi does not really work well with realtime control, but I am wondering if reading from input pins can be interrupted by the operating system. In ... More on raspberrypi.stackexchange.com
🌐 raspberrypi.stackexchange.com
April 21, 2020
🌐
The Robotics Back-End
roboticsbackend.com › home › raspberry pi gpio interrupts tutorial
Raspberry Pi GPIO Interrupts Tutorial - The Robotics Back-End
December 30, 2021 - Here are 3 more code example to show you different ways to use GPIO interrupts on your Raspberry Pi. First, let’s add a LED to our circuit. Connect the shorter leg to the ground, and in between add a resistor (330 Ohm here). Then connect the longer leg of the LED to GPIO 20. Goal: power on the LED when the button is pressed, power off the LED when the button is released (you might have to tweak the bouncetime if you press the button very fast). #!/usr/bin/env python3 import signal import sys import RPi.GPIO as GPIO BUTTON_GPIO = 16 LED_GPIO = 20 def signal_handler(sig, frame): GPIO.cleanup()
🌐
Raspberry Pi
projects-raspberry.com › how-to-use-interrupts-with-python-on-the-raspberry-pi-and-rpi-gpio
How to use interrupts with Python on Raspberry Pi and RPi.GPIO
September 2, 2025 - This tutorial explains how to use interrupts with Python on the Raspberry Pi using the RPi.GPIO library. It covers configuring GPIO pins, setting up event detection, and writing callback functions to respond to input changes immediately.
🌐
Raspberry Pi Forums
forums.raspberrypi.com › board index › community › general discussion
Interrupt for python - Raspberry Pi Forums
November 18, 2021 - I would handle that with threads and blocking I/O. I would create a thread who's responsibility was talking to the web server and pass it instructions in variables. The thread would send out the request and then wait for a response. When the response arrived the thread would do whatever the response required. All the interrupts are then internal to the Python interpretor and the program is simple.
🌐
YouTube
youtube.com › watch
Raspberry Pi - How to Handle GPIO Interrupts with Python 3 - YouTube
Learn how to use GPIO interrupts on your Raspberry Pi, using the RPi.GPIO library. Step by step explanation for both wait_for_edge() and add_event_detect() f...
Published   December 16, 2021
Find elsewhere
🌐
Raspberry Pi Forums
forums.raspberrypi.com › board index › programming › python
Timer Interrupt with Python 3 - Raspberry Pi Forums
Then I thought about the pointers of C language but didn't find anything of that kind in python. I hope my English is good enough to understand me ... Thank's again, Tarty ... After your "def hello():" add another line "global a". At the moment your "a=1" is creating and setting a local variable known only within the hello routine, not the global variable which others will have access to. ... I am not familiar with the code but a quick read suggested to me that the callback or interrupt function would have to restart the timer if you want it to be periodic, otherwise it will fire once and stop.
🌐
Raspberry Pi Forums
forums.raspberrypi.com › board index › programming › python
how do interrupts work on rpi4 - Raspberry Pi Forums
March 14, 2023 - Linux then notifies any software which has registered an interest in that interrupt. That might e.g. be a Python script or a C program etc. If the program is not running it will have to be scheduled to run. If the program is running the relevant thread within the program will have to be triggered. That is what introduces the latency. pigpio adds another method, it uses DMA to provide regular snapshots of the GPIO.
🌐
Scribd
scribd.com › doc › 227356016 › How-to-Use-Interrupts-With-Python-on-the-Raspberry-Pi-and-RPi
How To Use Interrupts With Python On The Raspberry Pi and RPi | PDF | Raspberry Pi | Callback (Computer Programming)
This document discusses using interrupts with Python on the Raspberry Pi. It explains that interrupts allow a program to respond immediately to an event without constantly checking for it. This saves processing power.
🌐
AB Electronics UK
abelectronics.co.uk › home › help and support › knowledge base › io pi plus tutorials › io pi plus tutorial 4 - more interrupts
IO Pi Tutorial 4 - More Interrupts IO Pi Interrupts
July 30, 2024 - The IO Pi Plus is supplied with Bus 1 on I2C address 0x20 and Bus 2 on 0x21; if you have changed the I2C addresses, you must update the code below to use the new I2C addresses. The AB Electronics Python library uses another library called python3-smbus; you can install it using apt-get with the following commands. sudo apt-get update sudo apt-get install python3-smbus · The RPi.GPIO library is needed to configure and listen for events on the Raspberry Pi’s GPIO header.
Top answer
1 of 2
3

Python may not be the best choice if you have high or sustained data rates. You would be much better off using C.

Try the following Python. It should capture all the interrupts although if you have sustained high interrupt rates it may take time for them all to be processed.

#!/usr/bin/env python

import time

import pigpio # http://abyz.me.uk/rpi/pigpio/python.html

pi = pigpio.pi()
if not pi.connected:
   exit(0)

cb = pi.callback(21)

while True:
   print(cb.tally())
   cb.reset_tally()
   time.sleep(1)
2 of 2
1

You can handle high speed interrupts on the R'Pi using Python easily if you make some configuration changes:

  1. Constrain operation to cpu 0,1,2 for the 'Pi
  2. Never do prints in the interrupt routines
  3. Set syscheckinterval to a large value to reduce overhead
  4. When you start your Python app, remap to cpu 3 and set the priority to realtime (-20)

This will allow you to get quite good response out to 5+kHz interrupt rates with no delays.

Here's some sample code:

#! /usr/bin/python2

##Interupt driven x1, x2 up/down encoder counter
##Jack Creasey

from RPi import GPIO
import os
import sys

##*********************************
#Define pin usage for encoder
#**********************************
phase_a = 21   
phase_a_dash= 16
phase_b = 20

##*********************************
#Define pin usage for PWM 
#**********************************
pwm_out = 12                #connect pin 12 to pin 24 to create a pwm timer interrupt
pwm_in = 24

#**********************************
#Setup GPIO
#**********************************

GPIO.setwarnings(False)
GPIO.cleanup()
GPIO.setmode(GPIO.BCM)
GPIO.setup(phase_a, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(phase_a_dash, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(phase_b, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(pwm_in, GPIO.IN, pull_up_down=GPIO.PUD_UP)

GPIO.setup(pwm_out, GPIO.OUT)  # Set GPIO pin 12 to output mode.
pwm = GPIO.PWM(pwm_out, 200)   # Initialize PWM pin and frequency
pwm.start(5)                   # Start PWM with 5% duty cycle


#**********************************
#Global variables
#**********************************
global counter
global lastcounter
global pwmticks
global lastpwmticks



def setup():

    #Find out our pid so we can remap to cpu 3
    mypid=os.getpid()
    myppid=os.getppid()

    print("My pid is "), mypid

    print('Setting cpu affinity to cpu 3')
    select_cpu="sudo taskset  -cp 3 "
    print('Setting priority to -20')
    set_priority="sudo renice -n -20 -p "

    #Call out to the os to remap the cpu and set priority high
    ret=os.system(set_priority+str(mypid))
    ret=os.system(select_cpu+str(mypid))

    sys.setcheckinterval(1000); ##no Python threading so just let Python run for a long time




def my_callback(channel):       #x1 sensing

    global counter

    if GPIO.input(phase_b):
            counter += 1
    else:
            counter -= 1

def my_callback1(channel):      #x2 sensing

    global counter

    if GPIO.input(phase_b):
            counter -= 1
    else:
            counter += 1

def my_callback2(channel):      #PWM interrupt 

    global pwmticks

    pwmticks += 1


setup()
counter = 0
lastcounter=counter

pwmticks=0
lastpwmticks=pwmticks

GPIO.add_event_detect(phase_a, GPIO.FALLING  , callback=my_callback)        #x1
GPIO.add_event_detect(phase_a_dash, GPIO.RISING  , callback=my_callback1)   #x2
GPIO.add_event_detect(pwm_in, GPIO.RISING  , callback=my_callback2)



try:

    while True:                             #busy work for Python main loop to do
        if counter != lastcounter:
            lastcounter=counter
            sys.stdout.write("\r" + str(counter) + "   \r")
            sys.stdout.flush()

        if pwmticks >= (lastpwmticks + 1000):
            lastpwmticks=pwmticks
            sys.stdout.write("\n Ticks= " + str(lastpwmticks) + "   \n")
            sys.stdout.flush()

except KeyboardInterrupt:
      print("Ctl C pressed - ending program") 
🌐
Medium
medium.com › @rxseger › interrupt-driven-i-o-on-raspberry-pi-3-with-leds-and-pushbuttons-rising-falling-edge-detection-36c14e640fef
Interrupt-driven I/O on Raspberry Pi 3 with LEDs and pushbuttons: rising/falling edge-detection using RPi.GPIO | by R. X. Seger | Medium
August 22, 2016 - Sounds complicated, fortunately the RPi.GPIO Python module included in Raspbian supports interrupts nearly as easily as polling. Raspberrywebserver.com’s Using Interrupt Driven GPIO is a good introduction.
🌐
Adafruit
blog.adafruit.com › 2013 › 03 › 22 › how-to-use-interrupts-with-python-on-the-raspberry-pi-and-rpi-gpio
How to use interrupts with Python on the Raspberry Pi and RPi.GPIO
March 22, 2013 - How to use interrupts with Python on the Raspberry Pi and RPi.GPIO This is the first in a series of articles which aim to show you how to use this new interrupt facility in Python. Interrupts are a…
Top answer
1 of 1
1

Linux as shipped with the Pi is not a real time operating system but version do exist called RTOS or RT Linux and some kernel mods for the Pi have been seen in the wild to give some added ability.

Add onto this, Python is an interpreted language and can suffer from the Global Interpreter locking threads let alone from the OS wanting the CPU for its own tasks.

Python brings its own multi-threading and multi-process libraries to help getting more than one thing done.

You are always limited by the OS, devices attached to the CPU and native programming so ‘real-time’ is not something a multitasking computer is very good at.

In your case, it is always possible to lose data (see Tom Scott on YouTube for why no message can be 100% guaranteed) and this is why check routines and hardware signalling has been part of computing since day one.

Remember some communications subsystems on the Pi are handled by the OS (disk / serial / USB) and they operate at speeds in excess of normal GPIO based data transfers by building in checks and correct hardware design.

If you are looking for robust communication, you need to look at:

  • Interrupt driven capture so the link disrupts the normal program flow not the other way around.
  • Limiting what the machine is doing outside of data communications
  • Have a fast enough processor and memory and disk etc etc to handle all the demands
  • Building control signalling (either hardware or software) into the link
  • Building checks into the data so you know it’s correct or not
  • Look at using buffers (Python Queues being one way) where processing is separate from capture
  • Look at using extra hardware to provide a buffer between the high speed data and the slow speed data.

I think you will be surprised as to the amount of data and speed the Pi can handle BUT it depends on the application and connections.

🌐
Stack Overflow
stackoverflow.com › questions › 26724538 › use-interrupts-with-python-with-raspberry-pi-b
Use interrupts with python with Raspberry Pi B+ - Stack Overflow
wpi = wiringpi2.GPIO(wiringpi2.GPIO.WPI_MODE_PINS) wpi.pullUpDnControl(2,wpi.PUD_UP) wpi.wiringPiISR(2, wpi.INT_EDGE_RISING, my_callback()) ... Marina, you mention a link -- is your issue related to making GPIO module imports working on your RPi, or is your issue related to successfully cross-validated installation ( conform to the RPi.GPIO 0.5.1 ) but failing to handle the hardware interrupts?
🌐
Electrocredible
electrocredible.com › home › embedded systems › raspberry pi pico › raspberry pi pico interrupts tutorial- examples in micropython
Raspberry Pi Pico Interrupts Tutorial- Examples in MicroPython
April 10, 2025 - Here we discuss how to trigger external interrupts on Raspberry Pi Pico and interface push buttons using polling and interrupts. MicroPython will be used in this tutorial.
🌐
pytz
pythonhosted.org › RPIO › rpio_py.html
RPIO, the Python module — RPIO 0.10.0 documentation
RPIO.py extends RPi.GPIO in various ways, and uses the BCM GPIO numbering scheme by default · RPIO can listen for two kinds of interrupts: GPIO and TCP. GPIO interrupts happen when the state on a specific GPIO input changes. TCP interrupts happen when a TCP socket client sends a message
🌐
Quorten Blog 1
quorten.github.io › quorten-blog1 › blog › 2020 › 09 › 12 › rpi-gpio-int-uspace
A more elegant way to get Raspberry Pi GPIO interrupts in user-space | Quorten Blog 1
September 12, 2020 - Linux epoll is the name of the game for registering Raspberry Pi GPIO interrupts into your user-space code. 20200912/DuckDuckGo linux epoll 20200912/https://en.wikipedia.org/wiki/Epoll · Well… looking further into the programming interface, it isn’t ideal for what I was thinking. epoll needs to be used in a waiting loop, so if you want an interrupt service routine style interface, then you need to spawn a thread to handle the waiting loop.