0

This is my complete code, that does not work as expected. The issue is if f_trigger def while loop runs, then f_reset is deaf - not listening anymore and not triggered. therefore alarm_cancel is never turned to True. Is this something documented, that if loop runs in one callback function, then another callback is ignored?

import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)

_gpin = 11
_gpin_reset = 12

alarm_cancel = False

def f_trigger(channel):
    global alarm_cancel
    while alarm_cancel == False:
        print('alarm cancel status: %s' % (alarm_cancel))
        time.sleep(.3)
    alarm_cancel = False

def f_reset(channel):
    global alarm_cancel
    print('f_reset called')
    alarm_cancel = True


# Define INPUTs
GPIO.setup(
    _gpin,
    GPIO.IN,
    pull_up_down=GPIO.PUD_UP
)  # input #1

# Trigger #1
GPIO.add_event_detect(
    _gpin, GPIO.BOTH, callback=f_trigger, bouncetime=100
)

# Define INPUTs
GPIO.setup(
    _gpin_reset,
    GPIO.IN,
    pull_up_down=GPIO.PUD_UP
)  # input #2

# Trigger #2
GPIO.add_event_detect(
    _gpin_reset, GPIO.BOTH, callback=f_reset, bouncetime=100
)

while True:
    print('main thread loop running')
    time.sleep(60)

2 Answers 2

3

Callbacks are emitted by one thread. Each callback will therefore run to completion before the next is called.

This is true for RPi.GPIO and all the other Pi GPIO Python and C modules that I am aware of.

Treat callbacks as interrupts. Do the minimum possible before returning, e.g. set a flag to be picked up in the main thread.

1
  • Thanks for explanation, so i need to make different implementation
    – B.Ondrej
    Apr 13, 2021 at 17:11
0

Another option that will make multiple callback work together is to use threading like in example below and run the callback function with loop as specific thread, then if another callback function sets flag to True, this thread will still be able to read the alarm_cancel flag:

import threading

def f_trigger(channel):
        threading.Thread(name='_thread_fireup_alarm', target=fireup_alarm, args=(channel,)).start()


def fireup_alarm(channel):
    global alarm_cancel
    while alarm_cancel == False:
        print('alarm cancel status: %s' % (alarm_cancel))
        time.sleep(1)
    alarm_cancel = False

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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