1

Not sure if my problem is related to RaspberryPi, GPIO or just my understanding of Python but since I'm detecting my problem while playing with a button attached to my PI I ask it here.

I have a simple setup which just connects a button to port 26. When the button is pressed I set canExit to True in the hope the main while loop will stop. This does not happen. Can somebody explain me why ?

import time
import sys
import RPi.GPIO as GPIO
from gpiozero import Button

BUTTON_PIN=26
button = Button(BUTTON_PIN)

canExit=False

def onButtonPress():
    print("button pressed")
    canExit=True
    print("end of logic")

def cleanup(): #(signal, frame): 
    GPIO.setmode(GPIO.BCM)
    GPIO.cleanup()
    print("end of program")
    sys.exit(0)

button.when_pressed=onButtonPress
print("Please press a button")
while not(canExit):
    print("*",end="")
    time.sleep(0.1)
print("Nearly there, just cleaning up")
cleanup()

My output:

Please press a button
**************************button pressed
end of logic
*********************************************************************

But my program doesn't stop. The "Nearly there" is never printed and the cleanup() is not executed. The while loop keeps running

2

The problem is Python's variable scope.

The canExit variable in the onButtonPress function is not the same as the canExit variable in the outer scope.

To use the outer scope variable you need to specify canExit as global as follows.

def onButtonPress():
    global canExit
    print("button pressed")
    canExit=True
    print("end of logic")
  • So my problem can be reduced to my lack of python knowledge. Thank you very much. My program now exits in a clean way. – Conffusion Jun 9 at 22:39
1

In your program, you turn canExit to True on button press, but I don't see you use that to exit the program anywhere.

import sys
sys.exit()

This is a standard way to exit programs in Python, and I see you use this in cleanup(), and you call cleanup() at the end of your code. You can use an if or while to check the status of canExit, and then execute sys.exit() there.

You can find more details on sys.exit() - https://docs.python.org/2/library/constants.html#exit

See this answer, which is closely related to your question - https://stackoverflow.com/questions/73663/terminating-a-python-script

Edit: I don't have a RasPi near me to test or try a code to help you further. So, you can try and let me know if you face any difficulty on that.

  • sys.exit(0) is the last statement of the cleanup function which is called at the end of the program. But it is never executed because the while loop never stops. – Conffusion Jun 9 at 18:42
  • And, there is no exit for the while loop. Once inside the loop, it will never exit, because there is no status check for canExit within that while. That execution may not be the best way. Instead, use cleanup() inside the while, and the messages outside it. – Dr.Viper Jun 9 at 19:07
  • Maybe I'm wrong but I see it as 2 threads: the main flow loops until canExit becomes True, a second thread is started when pressing the button.The output shows the "end of logic" message after pressing the button. Just before this print canExit is set to True so I would expect the main while loop should end too. – Conffusion Jun 9 at 20:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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