Home > other >  A function is running despite me changing a variable that should stop it
A function is running despite me changing a variable that should stop it

Time:12-21

I was hoping someone could help me with this issue. I'm hoping it's fairly simple to fix, but I have been trying for a while to figure this out. I have trimmed my larger code to this, as I believe the issue here is the crux of the problem.

I have a raspberry pi and an external button. This is on python3 on Linux. I am using GPIOZero for the button. The code below I believe is simple to understand, but basically, I want a function to loop at all times. When I press a button I want another function to run, but only if a variable is a certain number. I describe what I ultimately want to happen in a comment below, but my code is unfinished and simplified just for this problem.

I only want button.when_pressed to work when timer = 0. The problem is, once the code naturally gets into the button.when_pressed function, it never "lets go" of the function again. When I successfully redefine the variable to timer = 1, it still prints button is pressed when I press the button. I don't know why. To me, it seems like it should only work once timer = 0.

Any suggestions? I think I have a misunderstanding of global variables I will plan on researching. I'm not sure if that's the issue. I have also tried using break and continue to try to get it "back on its loop" but that hasn't worked either. Also I want to use button.when_pressed instead of btn.is_pressed, because I want the program to only do something when I'm holding the button down once, and not loop when I'm holding it down. In this case, I want button is pressed to print a single time. If I did btn.is_pressed it would print button is pressed every two seconds, which I dont want.

Thanks for any help. I'm happy to learn.

#!/usr/bin/python3

from gpiozero import Button
from time import sleep
import time

button = Button(4)
timer = 0

def press():
    print("Button is pressed")
    global timer
    timer = 1
   
def loop():
    global timer
    timer =  1
   
while True:
       
    if timer == 0:
        button.when_pressed = press
   
    else:
        loop()

    sleep(2)

CodePudding user response:

If you want to disable the callback you had set to button.when_pressed, you need to do another assignment with button.when_pressed = None. This is listed in the documentation:

when_released:

[...] Set this property to None (the default) to disable the event.

It's not exactly clear what behavior you want from your current code. If you want the button to be active for 2 seconds, then be deactivated indefinitely, you can use:

button.when_pressed = press
sleep(2)
button.when_pressed = None

There's no need for a loop, since you don't want to repeat anything.

If you only want the button to be active for a single button press, that needs to happen within 2 seconds, you could instead call button.wait_for_press(2). I hesitate to write a full block of code for that though, as the docs don't specify how a timeout is signaled (it might be by return value, or via an exception). I don't have a Raspberry Pi so I can't test myself, but you could try it out and see what happens.

CodePudding user response:

Treat your whole piece of code as one "black box", ask yourself, what is the input/output? button press or timer mode? (because I don't quite understand what does timer variable mean in your code)

Your code implies timer mode is the top level input to control the flow,

while True:
    if timer == 0:
        button.when_pressed = press
    else:
        loop()
    sleep(2)

Is it expected?

If you allow user to press the button at any time, suggest you make button press to be your top level input, change the logic to keep when_pressed callback always on, set flag once triggered, and then check if the button has been pressed and still is_pressed in your while loop.

pressed = False

def play_video_1():
    pass

def play_video_2():
    pass

def press():
    print("Button is pressed")
    global pressed
    pressed = True


button.when_pressed = press

while True:
       
    if pressed and not_playing_video2:
        if is_pressed:
            play_video_1()
        else:
            pressed = False
            play_video_2()
    else:
        play_video_2()

  • Related