RPi.GPIO interrupt then make caller immediately return?

183 Views Asked by At

So right now I have two functions:

Def dostuff():
  # do stuff 1
  GPIO.add_event_detect(button,…,callback=Interrupt,…)
  # do stuff 2

Def Interrupt():
  # other stuff

When I run dostuff() it does stuff 1, registers the interrupt, then does stuff 2. When I press the button during do stuff 2 the interrupt gets called, does it’s things then return to dostuff() where it left off.

My issue is when I return from the interrupt I want it to call return True within dostuff() thus leaving the function call early. Basically acts as an abort switch for do stuff 2 as it takes a long time.

I’ve tried raising an exception in the interrupt and putting a try catch in dostuff() but apparently the raise exception doesn’t go back to the caller.

Adding a global variable isn’t really an option unless I want to do a check after every line in dostuff().

Having the interrupt call out to a different part of code to change execution works but if I end gracefully it’ll eventually return to the caller of the interrupt which is nasty and unclean.

Any ideas?

1

There are 1 best solutions below

0
On

One way how to achieve this is to turn do stuff 2 into separate process and kill the process in the Interrupt:

>>> process = subprocess.Popen("sleep 3 && echo end", shell=True)
>>> end
process = subprocess.Popen("sleep 3 && echo end", shell=True)
>>> process.kill()
>>> # No end here

You should prepare the callback when the process is created by something like this:

def createKiller(process):
    return lambda: process.kill()

and give callback like:

process = subprocess.Popen(["python", "do_stuff_2.py"] + your_args, stdout=subprocess.PIPE)
GPIO.add_event_detect(button,…,callback=createKiller(process),…)

then you wait for the result as:

>>> while process.poll() is None:
...   time.sleep(1)
...   print('waiting...')
... 
waiting...
waiting...
waiting...
>>> process.communicate()
(b'end\n', None)