add GPIO input detection

This commit is contained in:
ohsqueezy 2023-02-20 22:22:35 -05:00
parent 07e59c6ca1
commit fb1b34cecc
1 changed files with 53 additions and 0 deletions

View File

@ -6,8 +6,18 @@ import argparse, os, pathlib, pygame, sys
import lib.pgfw.pgfw as pgfw
from games.ibitfit.electric_sieve.ElectricSieve import ElectricSieve
# Import GPIO library if available
try:
import RPi.GPIO as GPIO
except ImportError:
pass
class Playzing(pgfw.Game):
# The GPIO pins corresponding to the buttons
PIN_BUTTON_LEFT = 17
PIN_BUTTON_RIGHT = 27
def __init__(self, config_overrides=None):
"""
Create logo sprite, clear screen, and subscribe to events.
@ -35,6 +45,10 @@ class Playzing(pgfw.Game):
# Clear screen to black
self.get_display_surface().fill(self.configuration.get("display", "clear"))
# Initialize GPIO input and callbacks if GPIO library is loaded
if "RPi.GPIO" in sys.modules:
self.initialize_gpio()
# Subscribe to PGFW command events
self.subscribe(self.respond)
@ -53,6 +67,45 @@ class Playzing(pgfw.Game):
self.register(self.reveal_text, interval=40)
self.play(self.animate_logo, play_once=True)
def initialize_gpio(self):
"""
Set pin numbering mode to GPIO, initialize all buttons to input pullup.
"""
# Use GPIO numbering
GPIO.setmode(GPIO.BCM)
# Set button pins to pullup and attach to each a callback that runs on press or release
for pin in self.PIN_BUTTON_LEFT, self.PIN_BUTTON_RIGHT:
GPIO.setup(pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.add_event_detect(pin, GPIO.BOTH, self.gpio_input)
def gpio_input(self, pin):
"""
Translate GPIO input into PGFW commands, so Raspberry Pi wired controllers be used for input.
Compare the pin state to what is stored in memory. Only fire an event if there has been a change in state. A change
from high to low triggers a press event. A change from low to high triggers a press cancel event.
@param pin Raspberry Pi pin number as read by the RPi.GPIO library
"""
# Print the input state of each pin if debug is requested on the command line
if "--debug" in sys.argv:
pin_name = "left" if pin == self.PIN_BUTTON_LEFT else "right"
left_pin_state = GPIO.input(self.PIN_BUTTON_LEFT)
right_pin_state = GPIO.input(self.PIN_BUTTON_RIGHT)
print(f"Received {pin} ({pin_name}) input. Left state is {left_pin_state}. Right state is {right_pin_state}")
# If the saved state of the pin is the same, there hasn't been a real button press or release, so don't continue
if self.pin_states[pin] != GPIO.input(pin):
self.pin_states[pin] = GPIO.input(pin)
# A high signal means the button is released, and a low signal means it is pressed
cancel = not (GPIO.input(pin) == GPIO.LOW)
if pin == self.PIN_BUTTON_LEFT:
self.input.post_command("left", cancel=cancel)
elif pin == self.PIN_BUTTON_RIGHT:
self.input.post_command("right", cancel=cancel)
self.input.post_any_command(id=pin, cancel=cancel)
@property
def rotated(self):
return self.configuration.get("display", "rotated")