'correct way to handle GPIO interrupts when using time.sleep()

I have the following scenario. With a raspberry pi I have a main function which runs in a while loop and alternates tasks between calls to sleep. I would like a button press to interrupt the main loop and do another task for a certain amount of time before returning to the main loop. In reality I am displaying output on an LCD screen but I coded up this simpler example to illustrate the problem with my logic. I think things are getting crossed up because both functions seem to be active at the same time? I don't know the correct way to handle this scenario. Can someone suggest how to do this properly?

from time import sleep
import RPi.GPIO as GPIO

BUTTON_PIN = 2  # GPIO pin for mode button

def main():
    print("mode1 part A")
    sleep(4)
    print("mode1 part B")
    sleep(4)

def run_mode_two():
    # I would like this function to full execute before retuning to main
    print("mode2")
    sleep(8)

# function to be called by interrupt
def button_released_callback(channel):
    run_mode_two()

# intialize gpio for button
GPIO.setmode(GPIO.BCM)
GPIO.setup(
    BUTTON_PIN, 
    GPIO.IN, 
    pull_up_down = GPIO.PUD_UP)

# interrupt to listen for button push
GPIO.add_event_detect(
    BUTTON_PIN, 
    GPIO.RISING,
    callback = button_released_callback,
    bouncetime = 300)

while True:
    main()


Solution 1:[1]

The following pseudo code for your reference. Only focus on the flow, please adapt it to your own needs.


    mode = 1
    
    def button_callback():
        mode = 2
        start_timer(5)
    
    def timer_callback():
        mode = 1
    
    def loop():
        if mode == 1:
            # run code in mode 1
        else:
            # run code in mode 2
    
    def main():
        # init code here
        # ...
        while True:
            loop()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 balun