Search code examples
pythonraspberry-pigpio

Using an IF statement in Python inside of a main() function


I am trying to create a program that detects the state of three different buttons, connected to GPIO pins on a Raspberry Pi, and once all three have been HIGH once, an action is taken. Right now I have all the buttons working individually through callback functions, but the if statement inside the 'main' function does not seem to be running.

This is my first time using Python so please let me know if you see any other logical errors in the structure of my code. Still trying to get a hang of it, especially the GPIO library functions. Thanks in advance, I've posted my code below.

import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)

butOne = False
butTwo = False
butThree = False

# Setup button inputs
GPIO.setup(19, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(20, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(21, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

GPIO.add_event_detect(19, GPIO.RISING)
GPIO.add_event_detect(20, GPIO.RISING)
GPIO.add_event_detect(21, GPIO.RISING)

def butOne_callback(channel1):
    print("Button 1 /n")
    butOne = True

def butTwo_callback(channel2):
    print("Button 2 /n")
    butTwo = True

def butThree_callback(channel3):
    print("Button 3 /n")
    butThree = True

def main():
    GPIO.add_event_callback(19, butOne_callback)
    GPIO.add_event_callback(20, butTwo_callback)
    GPIO.add_event_callback(21, butThree_callback)

    if (butOne == True) and (butTwo == True) and (butThree == True):
        print("All Depressed")
main()

UPDATED CODE, according to Aditya Shankar's suggestions:

import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)

GPIO.setup(19, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(20, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(21, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

GPIO.add_event_detect(19, GPIO.RISING)
GPIO.add_event_detect(20, GPIO.RISING)
GPIO.add_event_detect(21, GPIO.RISING)

def butOne_callback(channel1):
    print("Button 1 /n")
    butOne = True
    check_all_depressed()

def butTwo_callback(channel2):
    print("Button 2 /n")
    butTwo = True
    check_all_depressed()

def butThree_callback(channel3):
    print("Button 3 /n")
    butThree = True
    check_all_depressed()

def check_all_depressed():
    if butOne and butTwo and butThree:
        print("All Depressed")

GPIO.add_event_callback(19, butOne_callback)
GPIO.add_event_callback(20, butTwo_callback)
GPIO.add_event_callback(21, butThree_callback)

Error received when code is run and button is pressed:

Traceback (most recent call last): File "/home/pi/Downloads/GPIO_test_06.py", line 21, in butTwo_callback check_all_depressed() File "/home/pi/Downloads/GPIO_test_06.py", line 29, in check_all_depressed if butOne and butTwo and butThree: NameError: name 'butOne' is not defined


Solution

  • Answer:

    remove the if condition

    add a function check_all_depressed()

    add the function to the end of all three button callbacks, like this

    def butOne_callback(channel1):
        global butOne
        print("Button 1 /n")
        butOne = True
        check_all_depressed()
    

    check_all_depressed looks like this -

    def check_all_depressed():
        if butOne and butTwo and butThree:
            print("All Depressed")
    

    Explanation: So, there are callbacks and there is general program flow. basically python programs follow an order of events of occurrence, that is top to bottom, callbacks occur outside this flow.