Display-O-Tron HAT - Handling Touch Events(?)


#1

Hi there!

I’m having a little trouble handling touch events with the Display-O-Tron HAT. Specifically, since getting mine last week, I’ve been trying to get some code to recognize that a button has been pressed. Right now, using the examples and reference, I have a series of decorated functions that just print the name of their corresponding button when the device says it’s pressed. But I’m not sure how to use that information as a condition (usable within an ‘if’ statement). I have each function returning ‘true’ but this doesn’t seem to help it, so I must be missing something!

My code looks like thus so far:

def Start():
    _t = Touch()
    while(self._guesses == 0):
        if(_t.handle_up):
            print("Yay!")
            self._guesses += 1

class Touch():
    @_touch.on(_touch.UP)
    def handle_up(channel, event):
        print("'UP' pressed")
        return True

So right now - as-per the example - the program outputs that “up” is pressed, but it doesn’t print “Yay!”. Any help would be very much appreciated!

Thanks!


#2

Ahoy!

Now this is an interesting one. The way Explorer HAT handles touch is “event driven”, and the functions you give it to handle a particular touch are squirrelled away within a list in the Explorer HAT module and run in a separate thread each time a touch event is recognised.

This means your return True is working, but it’s sending the return value to the bit of code that polls the touch sensor chip and calls the touch functions.

Perhaps the best way to fix this is to flip the logic on its head and make your game, or application a class that exposes some functions you want to run when a button is pressed.

Let’s think about it this way:

import time
import explorerhat

class My_App
    def __init__(self):
        self._guesses = 0
        # Some more initialization stuff and whatnot

    def handle_touch(self, channel, event):
        print("Handling a touch!")
        if event == "press":
            self._guesses += 1

    def run(self):
        while self._guesses == 0:
            print("No guesses yet!")
            time.sleep(1)
        while self._guesses == 1:
            print("One guess! Press again to exit")
            time.sleep(1)
       


my_app = My_App()

# Set up Explorer HAT to call our Apps touch handler on touch
@explorerhat.touch.pressed(my_app.handle_touch)
@explorerhat.touch.released(my_app.handle_touch)

my_app.run()

This is a really crude example, but it shows your ( or attempts to ) how you can create a method in your class that handles touch events, and exploit the fact that Explorer HAT implicitly threads any calls to this method.

Even though your Python program is stuck running the while self._guesses == 0 loop, when you press a button the my_app.handle_touch method is called asynchronously ( in a thread ) and can increment guesses.

Your run method could contain the main logic loop, and would probably be better with something like:

while self.running:
    # do stuff

So you can set running to False and stop the App in your touch handler at any point.

Sorry if this is all jargon to you, but I notice you’re using classes and decorators so I’ve gone slightly techno-babble!


#3

Hi again!

Thanks for your answer, it helped me with that particular problem! Though I now have yet another question along the same lines as the previous, if you might help me again.
So, I’m now trying to figure out how to handle these touch events without those events seemingly interrupting/supplanting my own code! Specifically, my code is as follows:

- game_guess.py - 
class Guess(object):
    def __init__(self):
        print("Started!")

    def START(self):
        _guess = 0
        while(_guess < 10):
            _guess += 1
            if(_guess == 10):
                break
    
    def H_LT(ch, ev):
        print("Test!")

- run.py - 
def main():
    _g = Guess()
    _t.on(_g.H_LT)
    _g.START()

if __name__ == '__main__':
    main()

So, when I normally declare a touch function like:

@_t.on(_t.UP)
def H_LT(ch, ev):
    print("Test!")

…within the ‘Guess’ class itself, it my loop wouldn’t work! Instead, it would just be waiting for touch events (and responding to them). Though the first code snippet doesn’t seem to work either! So my question is - for the Display-O-Tron HAT - where/how should I be declaring/writing these touch events within the code? Since implementing them as the examples suggest seems to have them take president over my own code (the loop doesn’t seem to start, nor to the prints fire).

The code is simplified from what I have, but the rest of the code is not of issue. It’s these bits particularly.

Thanks again, and kind regards,

Josh