0

Below is a simplified version of a program I have running on a Raspberry Pi that allows for opening and closing my garage door. It works great, except if the manual button is used to open/close the door the Status label in the GUI gets out of sync. I can get them back in sync by clicking the status button; however, I'm wondering if there's a way in the "mainloop" to "see" when the state of GPIO pin 23 changes and call the statusClick function?

import time
from tkinter import *
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)              # set the mode to access pins
GPIO.setup(21,GPIO.OUT)             # Relay To Trip Door Open/Close
GPIO.setup(23,GPIO.IN, GPIO.PUD_UP) # Opened/Closed Magnetic Contacts for Door

def doorClick():
    print('Door Button Clicked')
    GPIO.output(21, GPIO.HIGH)      # Set pin HIGH fir .5 seconds to trigger door to open/close
    time.sleep(.5)
    GPIO.output(21, GPIO.LOW)
    statusClick()

def statusClick():
    if GPIO.input(23) == GPIO.HIGH: # Check state of magnetic contacts - if HIGH door is Open
        msg = 'Door Is Open'
    else:
        msg = 'Door Is Closed'

    doorLabel.config(text = msg)

def close_window():
    window.destroy()
    print('Closed')

try:
    window = Tk()
    window.protocol("WM_DELETE_WINDOW", close_window)
    window.geometry("450x200+0+36")
    window.title("Garage Doors")
    window.configure(bg='#5f6b7d')

    doorButton = Button(window,text="Garage Door",font=('Constantia',14))
    doorButton.config(command=doorClick)

    statusButton = Button(window,text='Status',font=('Constantia',14))
    statusButton.config(command=statusClick)

    doorLabel = Label(window,text='',bg='Yellow',font=('Constantia',14))
    doorLabel.pack()
    doorButton.pack()
    statusButton.pack()

    statusClick()
    window.mainloop()

finally:
    print('Cleanup')
    GPIO.cleanup()
Pragmatic_Lee
  • 473
  • 1
  • 4
  • 10
  • Check if this helps https://stackoverflow.com/questions/23839982/is-there-a-way-to-press-a-button-without-touching-it-on-tkinter-python/23840401 – Ritwik G Apr 12 '21 at 16:37
  • Try to use `.after()` to call `statusClick()` inside `doorClick()`. – acw1668 Apr 13 '21 at 00:46
  • Thanks for the suggestion. I added window.after(1000,statusClick()) as the last statement in doorClick() hoping statusClick() would get called every second; however, it only gets called when the doorButton is clicked. I added a print statement in the statusClick function to see when it was being called. Of course in real like the time interval would be much more than every second. – Pragmatic_Lee Apr 13 '21 at 13:44
  • It should be `window.after(1000, statusClick)` instead. Using `.after()` is to delay the call of `statusClick()` a bit, so that there is enough time for the input PIN to change status. – acw1668 Apr 14 '21 at 03:55

0 Answers0