Skip to content Skip to sidebar Skip to footer

Python Raspberrypi Gpio Event Detection In Tkinter Failing

I'm having a strange problem detecting GPIO events on the Raspberry Pi using Python with Tkinter. Once the startGameButton is clicked, which calls the start_game function, a GPIO

Solution 1:

mainloop() do all job in program - it runs event function (and other functions) - one after the other - and it looks like multitasking. But if any of function work too long (for example it use while True or time.sleep() then mainloop can execute other functions.

So don't use time sleep() and long running loop but use root.after(time, function) to run some function repeatedly.

I can't test it but it could looks like this:

defmy_loop(self):
    if (time.time() - self.start_time) < self.game_time:
       print"listening"
       root.after(5000, self.my_loop) # run my_loop again after 5000 millisecondsdefstart_game(self):
        global p2score

        # use self. to get access in other function
        self.start_time = time.time()
        self.game_time = 30#length of game

        P1PIN = 23
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(P1PIN, GPIO.IN)
        GPIO.add_event_detect(P1PIN, GPIO.FALLING, callback=self.p2ScoreEvent)

        try:
            GPIO.add_event_detect(P1PIN, GPIO.FALLING, callback=self.p2ScoreEvent)
            self.my_loop() # run my_loop first timeexcept:
            print"Something went wrong..."
            GPIO.cleanup()

BTW:

you could use self.end_time to make less calculations

defmy_loop(self):
    if time.time() < self.end_time:
       print"listening"
       root.after(5000, self.my_loop) # run my_loop again after 5000 millisecondsdefstart_game(self):
        global p2score

        # use self. to get access in other function# self.game_time = 30 
        self.end_time = time.time() + 30

BTW:

We use classes and self. to not use global

All code could look like this:

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

classApp():

    def__init__(self, master):

        self.master = master

        self.frame = Frame(master)

        self.p2diagString = "Player 2 Score: "
        self.p2score = 0

        self.p2diag = StringVar()
        self.p2diag.set(self.p2diagString + str(self.p2score))

        p2Label = Label(self.frame, fg="white", bg="blue", textvariable=self.p2diag)
        p2Label.grid(row=1, column=1)

        self.startGameButton = Button(
            self.frame, text="Start Game!", command=self.start_game
        )
        self.startGameButton.grid(row=3, columnspan=2)

    defp2ScoreEvent(self, p1pin):
        print"ScoreEvent"

        self.p2score += 1
        self.p2diag.set(self.p2diagString + str(self.p2score))

    defstart_game(self):
        self.game_time = 30
        self.end_time = time.time() + self.game_time

        P1PIN = 23
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(P1PIN, GPIO.IN)
        GPIO.add_event_detect(P1PIN, GPIO.FALLING, callback=self.p2ScoreEvent)

        try:
            GPIO.add_event_detect(P1PIN, GPIO.FALLING, callback=self.p2ScoreEvent)
            self.my_loop()
        except:
            print"Something went wrong..."
            GPIO.cleanup()

    defmy_loop(self):
        if time.time() < self.end_time:
           print"listening"
           root.after(5000, self.my_loop) # run my_loop again after 5000 millisecondsdefrun(self):
        self.master.mainloop()

#----------------------------------------------------------------------

App(Tk()).run()

I put __init__ as first function in class - it easer to read it - everybody expect __init__ at the beginning of class.

I use str() in place of repl()

In class I don't use external variables. I have all variables inside.

Post a Comment for "Python Raspberrypi Gpio Event Detection In Tkinter Failing"