From 7fb1131c2eda5f2330f4e44d9984802f855e9381 Mon Sep 17 00:00:00 2001 From: frank Date: Fri, 13 Jan 2023 20:27:32 -0500 Subject: [PATCH] save previously detected pin state for buttons to avoid multiple fires --- electric_sieve/ElectricSieve.py | 35 ++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/electric_sieve/ElectricSieve.py b/electric_sieve/ElectricSieve.py index a65b04d..c351dde 100644 --- a/electric_sieve/ElectricSieve.py +++ b/electric_sieve/ElectricSieve.py @@ -60,6 +60,12 @@ class ElectricSieve(Game): "int": ["gradient", "height", "x-step"], "float": ["altitude-ratio", "spacing-factor", "velocity-ratio", "fade-speed"] }}) + + # Member dict for tracking pin state changes. Start at 1 because high means unpressed. + self.pin_states = { + self.PIN_BUTTON_LEFT: 1, + self.PIN_BUTTON_RIGHT: 1 + } # Rotate the display if requested on the command line or in the configuration if self.check_command_line("-rotate"): @@ -117,18 +123,29 @@ class ElectricSieve(Game): def gpio_input(self, pin): """ - Translate GPIO input into PGFW commands, so Raspberry Pi wired controllers be used for input. The pin will be checked for a low - signal, meaning the pin has been connected to ground, which is translated to a button press. If the low signal is not detected, it - is translated to a button release. Usually called as a callback by `GPIO.add_event_detect` but can be called directly. + 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 """ - cancel = not (GPIO.input(pin) == GPIO.LOW) - if pin == ElectricSieve.PIN_BUTTON_LEFT: - self.input.post_command("left", cancel=cancel) - elif pin == ElectricSieve.PIN_BUTTON_RIGHT: - self.input.post_command("right", cancel=cancel) - self.input.post_any_command(id=pin, cancel=cancel) + if "--debug" in sys.argv: + pin_name = "left" if pin == ElectricSieve.PIN_BUTTON_LEFT else "right" + left_pin_state = GPIO.input(ElectricSieve.PIN_BUTTON_LEFT) + right_pin_state = GPIO.input(ElectricSieve.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 == ElectricSieve.PIN_BUTTON_LEFT: + self.input.post_command("left", cancel=cancel) + elif pin == ElectricSieve.PIN_BUTTON_RIGHT: + self.input.post_command("right", cancel=cancel) + self.input.post_any_command(id=pin, cancel=cancel) def orient(self, geometry): """