diff --git a/adafruit_pybadger/clue.py b/adafruit_pybadger/clue.py index 4998612..debdbc3 100644 --- a/adafruit_pybadger/clue.py +++ b/adafruit_pybadger/clue.py @@ -27,12 +27,11 @@ from collections import namedtuple import board -import digitalio import audiopwmio -from gamepad import GamePad +import keypad import adafruit_lsm6ds.lsm6ds33 import neopixel -from adafruit_pybadger.pybadger_base import PyBadgerBase +from adafruit_pybadger.pybadger_base import PyBadgerBase, KeyStates __version__ = "0.0.0-auto.0" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_PyBadger.git" @@ -59,10 +58,10 @@ def __init__(self): board.NEOPIXEL, self._neopixel_count, brightness=1, pixel_order=neopixel.GRB ) - self._buttons = GamePad( - digitalio.DigitalInOut(board.BUTTON_A), - digitalio.DigitalInOut(board.BUTTON_B), + self._keys = keypad.Keys( + [board.BUTTON_A, board.BUTTON_B], value_when_pressed=False, pull=True ) + self._buttons = KeyStates(self._keys) @property def button(self): @@ -80,10 +79,11 @@ def button(self): elif pybadger.button.b: print("Button B") """ - button_values = self._buttons.get_pressed() - return Buttons( - button_values & PyBadgerBase.BUTTON_B, button_values & PyBadgerBase.BUTTON_A + self._buttons.update() + button_values = tuple( + self._buttons.was_pressed(i) for i in range(self._keys.key_count) ) + return Buttons(button_values[0], button_values[1]) @property def _unsupported(self): diff --git a/adafruit_pybadger/cpb_gizmo.py b/adafruit_pybadger/cpb_gizmo.py index 39530fb..29c23b1 100644 --- a/adafruit_pybadger/cpb_gizmo.py +++ b/adafruit_pybadger/cpb_gizmo.py @@ -32,11 +32,11 @@ import analogio import busio import audiopwmio +import keypad from adafruit_gizmo import tft_gizmo -from gamepad import GamePad import adafruit_lis3dh import neopixel -from adafruit_pybadger.pybadger_base import PyBadgerBase +from adafruit_pybadger.pybadger_base import PyBadgerBase, KeyStates __version__ = "0.0.0-auto.0" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_PyBadger.git" @@ -66,11 +66,11 @@ def __init__(self): self._neopixels = neopixel.NeoPixel( board.NEOPIXEL, self._neopixel_count, brightness=1, pixel_order=neopixel.GRB ) - _a_btn = digitalio.DigitalInOut(board.BUTTON_A) - _a_btn.switch_to_input(pull=digitalio.Pull.DOWN) - _b_btn = digitalio.DigitalInOut(board.BUTTON_B) - _b_btn.switch_to_input(pull=digitalio.Pull.DOWN) - self._buttons = GamePad(_a_btn, _b_btn) + + self._keys = keypad.Keys( + [board.BUTTON_A, board.BUTTON_B], value_when_pressed=True, pull=True + ) + self._buttons = KeyStates(self._keys) self._light_sensor = analogio.AnalogIn(board.LIGHT) @property @@ -89,10 +89,11 @@ def button(self): elif pybadger.button.b: print("Button B") """ - button_values = self._buttons.get_pressed() - return Buttons( - button_values & PyBadgerBase.BUTTON_B, button_values & PyBadgerBase.BUTTON_A + self._buttons.update() + button_values = tuple( + self._buttons.was_pressed(i) for i in range(self._keys.key_count) ) + return Buttons(button_values[0], button_values[1]) @property def _unsupported(self): diff --git a/adafruit_pybadger/mag_tag.py b/adafruit_pybadger/mag_tag.py index 2f8b849..be4e1a9 100644 --- a/adafruit_pybadger/mag_tag.py +++ b/adafruit_pybadger/mag_tag.py @@ -27,9 +27,6 @@ from collections import namedtuple import board - -# import digitalio -# from gamepad import GamePad import neopixel from adafruit_pybadger.pybadger_base import PyBadgerBase @@ -52,13 +49,6 @@ def __init__(self): board.NEOPIXEL, self._neopixel_count, brightness=1, pixel_order=neopixel.GRB ) - # self._buttons = GamePad( - # , - # digitalio.DigitalInOut(board.BUTTON_B), - # digitalio.DigitalInOut(board.BUTTON_C), - # digitalio.DigitalInOut(board.BUTTON_D), - # ) - @property def button(self): """The buttons on the board. @@ -75,11 +65,6 @@ def button(self): elif pybadger.button.b: print("Button B") """ - # button_values = self._buttons.get_pressed() - # return Buttons( - # button_values & PyBadgerBase.BUTTON_B, button_values & PyBadgerBase.BUTTON_A, - # button_values & PyBadgerBase.BUTTON_START, button_values & PyBadgerBase.BUTTON_SELECT - # ) @property def _unsupported(self): diff --git a/adafruit_pybadger/pewpewm4.py b/adafruit_pybadger/pewpewm4.py index cb6462a..7a6bbca 100644 --- a/adafruit_pybadger/pewpewm4.py +++ b/adafruit_pybadger/pewpewm4.py @@ -27,10 +27,9 @@ from collections import namedtuple import board -import digitalio import audioio -from gamepad import GamePad -from adafruit_pybadger.pybadger_base import PyBadgerBase +import keypad +from adafruit_pybadger.pybadger_base import PyBadgerBase, KeyStates __version__ = "0.0.0-auto.0" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_PyBadger.git" @@ -47,16 +46,22 @@ class PewPewM4(PyBadgerBase): def __init__(self): super().__init__() - self._buttons = GamePad( - digitalio.DigitalInOut(board.BUTTON_O), - digitalio.DigitalInOut(board.BUTTON_X), - digitalio.DigitalInOut(board.BUTTON_Z), - digitalio.DigitalInOut(board.BUTTON_RIGHT), - digitalio.DigitalInOut(board.BUTTON_DOWN), - digitalio.DigitalInOut(board.BUTTON_UP), - digitalio.DigitalInOut(board.BUTTON_LEFT), + self._keys = keypad.Keys( + [ + board.BUTTON_O, + board.BUTTON_X, + board.BUTTON_Z, + board.BUTTON_RIGHT, + board.BUTTON_DOWN, + board.BUTTON_UP, + board.BUTTON_LEFT, + ], + value_when_pressed=False, + pull=True, ) + self._buttons = KeyStates(self._keys) + @property def button(self): """The buttons on the board. @@ -73,20 +78,18 @@ def button(self): elif pybadger.button.o: print("Button O") """ - button_values = self._buttons.get_pressed() + self._buttons.update() + button_values = tuple( + self._buttons.was_pressed(i) for i in range(self._keys.key_count) + ) return Buttons( - *[ - button_values & button - for button in ( - PyBadgerBase.BUTTON_B, - PyBadgerBase.BUTTON_A, - PyBadgerBase.BUTTON_START, - PyBadgerBase.BUTTON_SELECT, - PyBadgerBase.BUTTON_RIGHT, - PyBadgerBase.BUTTON_DOWN, - PyBadgerBase.BUTTON_UP, - ) - ] + button_values[0], + button_values[1], + button_values[2], + button_values[3], + button_values[4], + button_values[5], + button_values[6], ) @property diff --git a/adafruit_pybadger/pybadge.py b/adafruit_pybadger/pybadge.py index 083b727..e873809 100644 --- a/adafruit_pybadger/pybadge.py +++ b/adafruit_pybadger/pybadge.py @@ -35,10 +35,10 @@ import digitalio import analogio import audioio -from gamepadshift import GamePadShift +import keypad import adafruit_lis3dh import neopixel -from adafruit_pybadger.pybadger_base import PyBadgerBase +from adafruit_pybadger.pybadger_base import PyBadgerBase, KeyStates __version__ = "0.0.0-auto.0" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_PyBadger.git" @@ -77,11 +77,14 @@ def __init__(self): board.NEOPIXEL, self._neopixel_count, brightness=1, pixel_order=neopixel.GRB ) - self._buttons = GamePadShift( - digitalio.DigitalInOut(board.BUTTON_CLOCK), - digitalio.DigitalInOut(board.BUTTON_OUT), - digitalio.DigitalInOut(board.BUTTON_LATCH), + self._keys = keypad.ShiftRegisterKeys( + clock=board.BUTTON_CLOCK, + data=board.BUTTON_OUT, + latch=board.BUTTON_LATCH, + key_count=8, + value_when_pressed=True, ) + self._buttons = KeyStates(self._keys) self._light_sensor = analogio.AnalogIn(board.A7) @@ -106,21 +109,19 @@ def button(self): print("Button select") """ - button_values = self._buttons.get_pressed() + self._buttons.update() + button_values = tuple( + self._buttons.was_pressed(i) for i in range(self._keys.key_count) + ) return Buttons( - *[ - button_values & button - for button in ( - PyBadgerBase.BUTTON_B, - PyBadgerBase.BUTTON_A, - PyBadgerBase.BUTTON_START, - PyBadgerBase.BUTTON_SELECT, - PyBadgerBase.BUTTON_RIGHT, - PyBadgerBase.BUTTON_DOWN, - PyBadgerBase.BUTTON_UP, - PyBadgerBase.BUTTON_LEFT, - ) - ] + button_values[0], + button_values[1], + button_values[2], + button_values[3], + button_values[4], + button_values[5], + button_values[6], + button_values[7], ) diff --git a/adafruit_pybadger/pybadger_base.py b/adafruit_pybadger/pybadger_base.py index dc187d7..7aa76c9 100644 --- a/adafruit_pybadger/pybadger_base.py +++ b/adafruit_pybadger/pybadger_base.py @@ -745,3 +745,46 @@ def play_file(self, file_name): while audio.playing: pass self._enable_speaker(enable=True) + + +class KeyStates: + """Convert `keypad.Event` information from the given `keypad` scanner into key-pressed state. + + :param scanner: a `keypad` scanner, such as `keypad.Keys` + """ + + def __init__(self, scanner): + self._scanner = scanner + self._pressed = [False] * self._scanner.key_count + self.update() + + def update(self): + """Update key information based on pending scanner events.""" + + # If the event queue overflowed, discard any pending events, + # and assume all keys are now released. + if self._scanner.events.overflowed: + self._scanner.events.clear() + self._scanner.reset() + self._pressed = [False] * self._scanner.key_count + + self._was_pressed = self._pressed.copy() + + while True: + event = self._scanner.events.get() + if not event: + # Event queue is now empty. + break + self._pressed[event.key_number] = event.pressed + if event.pressed: + self._was_pressed[event.key_number] = True + + def was_pressed(self, key_number): + """True if key was down at any time since the last `update()`, + even if it was later released. + """ + return self._was_pressed[key_number] + + def pressed(self, key_number): + """True if key is currently pressed, as of the last `update()`.""" + return self._pressed[key_number] diff --git a/adafruit_pybadger/pygamer.py b/adafruit_pybadger/pygamer.py index d4d1759..784a290 100644 --- a/adafruit_pybadger/pygamer.py +++ b/adafruit_pybadger/pygamer.py @@ -31,9 +31,9 @@ import digitalio import audioio import neopixel -from gamepadshift import GamePadShift +import keypad import adafruit_lis3dh -from adafruit_pybadger.pybadger_base import PyBadgerBase +from adafruit_pybadger.pybadger_base import PyBadgerBase, KeyStates __version__ = "0.0.0-auto.0" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_PyBadger.git" @@ -65,11 +65,14 @@ def __init__(self): board.NEOPIXEL, self._neopixel_count, brightness=1, pixel_order=neopixel.GRB ) - self._buttons = GamePadShift( - digitalio.DigitalInOut(board.BUTTON_CLOCK), - digitalio.DigitalInOut(board.BUTTON_OUT), - digitalio.DigitalInOut(board.BUTTON_LATCH), + self._keys = keypad.ShiftRegisterKeys( + clock=board.BUTTON_CLOCK, + data=board.BUTTON_OUT, + latch=board.BUTTON_LATCH, + key_count=4, + value_when_pressed=True, ) + self._buttons = KeyStates(self._keys) self._pygamer_joystick_x = analogio.AnalogIn(board.JOYSTICK_X) self._pygamer_joystick_y = analogio.AnalogIn(board.JOYSTICK_Y) @@ -97,13 +100,16 @@ def button(self): print("Button select") """ - button_values = self._buttons.get_pressed() + self._buttons.update() + button_values = tuple( + self._buttons.was_pressed(i) for i in range(self._keys.key_count) + ) x, y = self.joystick return Buttons( - button_values & PyBadgerBase.BUTTON_B, - button_values & PyBadgerBase.BUTTON_A, - button_values & PyBadgerBase.BUTTON_START, - button_values & PyBadgerBase.BUTTON_SELECT, + button_values[0], + button_values[1], + button_values[2], + button_values[3], x > 50000, # RIGHT y > 50000, # DOWN y < 15000, # UP diff --git a/docs/conf.py b/docs/conf.py index d2c5565..1b6b30c 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -8,6 +8,7 @@ import sys sys.path.insert(0, os.path.abspath("..")) +sys.path.insert(0, os.path.abspath("mocks")) # -- General configuration ------------------------------------------------ @@ -28,13 +29,11 @@ autodoc_mock_imports = [ "audioio", "displayio", - "gamepadshift", "neopixel", "analogio", "terminalio", "adafruit_lis3dh", "adafruit_lsm6ds", - "gamepad", "audiocore", "audiopwmio", "micropython", diff --git a/docs/mocks/keypad.py b/docs/mocks/keypad.py new file mode 100644 index 0000000..5fcd12a --- /dev/null +++ b/docs/mocks/keypad.py @@ -0,0 +1,32 @@ +# SPDX-FileCopyrightText: 2021 Jeff Epler for Adafruit Industries +# +# SPDX-License-Identifier: MIT +class EventQueue: + def __init__(self): + self.overflowed = False + + def get(self): + return None + + +class Keys: + def __init__(self, pins, value_when_pressed, pull): + self.key_count = len(pins) + self.events = EventQueue() + + +class ShiftRegisterKeys: + def __init__( + self, + *, + clock, + data, + latch, + value_to_latch=True, + key_count, + value_when_pressed, + interval=0.020, + max_events=64 + ): + self.key_count = 123 + self.events = EventQueue()