Arnold Farkas
Arnold Farkas

Reputation: 35

How to interrupt GPIO button triggered long running process with another event on Raspberry Pi?

I have 2 buttons wired to a Rapsberry Pi Zero W on the 38 and 40 pins. I have a long running process triggered to pin38 and I'd like to interrupt it once the pin40 is pushed. But pin 40 is inactive while the callback of pin38 is running. How can the long running proccess stopped via another event?

import RPi.GPIO as GPIO
import time

should_stop = False


def cb1(pin):
    if GPIO.input(pin) == 0:
        print("long running:", pin)

        global should_stop
        should_stop = False

        for _ in range(10):
            if not should_stop:
                print("long running is running")
                time.sleep(1)

        print("long running DONE")


def interrupt(pin):
    if GPIO.input(pin) == 0:
        print("fast running:", pin)

        global should_stop
        should_stop = True


GPIO.setmode(GPIO.BOARD)

GPIO.setup(38, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(40, GPIO.IN, pull_up_down=GPIO.PUD_UP)

GPIO.add_event_detect(38, GPIO.RISING, callback=cb1, bouncetime=300)
GPIO.add_event_detect(40, GPIO.RISING, callback=interrupt, bouncetime=300)

while True:
    time.sleep(1)

Upvotes: 1

Views: 1522

Answers (1)

Dan Ionescu
Dan Ionescu

Reputation: 3423

I've tested the following code on a PI and it works, it's using python a python process:

import RPi.GPIO as GPIO

import multiprocessing
import time

# function responsable for doing the heavy work when button1 is pressed
# this function will stop doing the work when button 2 is pressed
def long_processing(e):
    # runs for ever
    while True:
        # waits until the event is set
        e.wait()
        # do work while the event is set
        while e.is_set():
            # do some intensive work here
            print('intensive work...')
            time.sleep(0.5)


if __name__ == '__main__':
    # initialize GPIO buttons
    GPIO.setmode(GPIO.BOARD)
    button1_pin = 16
    button2_pin = 12
    GPIO.setup(button1_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    GPIO.setup(button2_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)

    first_button_pushed = multiprocessing.Event()

    # GPIO callbacks
    def but1_callback(channel):
        print('first button bushed')
        first_button_pushed.set()

    def but2_callback(channel):
        print('second button bushed')
        first_button_pushed.clear()

    # GPIO callbacks hooks
    GPIO.add_event_detect(button1_pin, GPIO.RISING, callback=but1_callback, bouncetime=300)
    GPIO.add_event_detect(button2_pin, GPIO.RISING, callback=but2_callback, bouncetime=300)

    # a process used to run the "long_processing" function in background
    # the first_button_pushed event is passed along
    process = multiprocessing.Process(name='first_process', target=long_processing, args=(first_button_pushed,))
    process.daemon = True
    process.start()

    while True:
        time.sleep(1)

Upvotes: 1

Related Questions