2

Using a Pi 3+ in an animated display. The servos in the display are run from a 16 channel "bonnet" on the Pi. I am using RPI.GPIO to deal with GPIO issues.

What I want is for one set of instructions to run the servos until a sensor triggers a GPIO pin. Then, a second set of instructions needs to run. When that set of instructions is finished, I need to go back to the original set of instructions. This should continue ad infinitum.

So - the first set of instructions is like a holding pattern waiting for the interrupt.

I have both sets of instructions working. Am having difficulty implementing the description above.

Am using GPIO.add_event_detect(Pin, callback, debounce) to call a function that runs the second set of instructions. What I get, when the interrupt is sensed, is both sets of instructions trying to run at the same time. I think this is multi-threading which is not what I want.

Is there a way to run one set of instructions at a time and then revert back to the original ?

4
  • 1
    But interrupt is already Raspbian's build in, system level muti-threading. You don't need to use python multi-threading module for higher level stuff.
    – tlfong01
    Commented Aug 17, 2020 at 2:44
  • 2
    If you are going to use python forget threading (GIL prevents threads from running in parallel) - which isn't needed. Asking general questions without code is futile. I suggest you forget RPI.GPIO and try gpiozero.
    – Milliways
    Commented Aug 17, 2020 at 3:19
  • 1
    Interrupts do not create or require additional threads; that they are "system level mutli-threading" is a perversion of the truth; they're more of a context switch. "What I get, when the interrupt is sensed, is both sets of instructions trying to run at the same time. I think this is multi-threading which is not what I want." -> To the contrary, what would solve your problem is multi-threading w/ synchronisation mechanisms (but I do not think python can really supply that)...
    – goldilocks
    Commented Aug 17, 2020 at 15:47
  • 1
    ... The problem with "things happening at the same time" is really only one thread having to handle interrupts in the middle of doing something else. -- hence event based patterns are considered asynchronous (which does not mean event handling can't be synchronised in one thread, but it is more awkward than with threads, and the need to do so may indicate a significant design flaw). I know this information is not a solution to your problem, but it should help you to think more clearly about what actually is and is not happening.
    – goldilocks
    Commented Aug 17, 2020 at 15:47

1 Answer 1

2

This is a pretty general question. Not specific to the Pi.

Anyhow what you need to do is set a flag in your callback. Something like was_called. Check this variable regularly in the main loop and switch code. Once you have seen the flag you need to reset it to prevent multiple invocations for the same event.

Sort of like the following pseudo code.

was_called = False

def callback(channel):
   global was_called
   was_called = True

...
while True:

   if was_called:
      was_called = False
      # switch code
...
2
  • 1
    Joan's use of a flag here is an example of what I meant by "synchronising event handling in a single thread" in my comments on the question.
    – goldilocks
    Commented Aug 17, 2020 at 15:53
  • Using Python for real time interrupt handling that needs synchronisation is not going to work. If you look up a book on real time programming you'll find details of how to use semaphores. A semaphore is a flag that can be tested and set in one non-interruptible operation. Any other check and set operation risks two processes checking the flag, seeing it is clear and both going to set the flag and clash with each other. Multicore architectures such the Pi can also confuse the situation even more. Real time programming is really for the professionals using the likes of Ada.
    – Nick
    Commented Aug 18, 2020 at 20:28

Not the answer you're looking for? Browse other questions tagged or ask your own question.