class MainLoop: def __init__(self): self.on_button_a = None # Set up the game pad self._pad = GamePadShift(DigitalInOut(board.BUTTON_CLOCK), DigitalInOut(board.BUTTON_OUT), DigitalInOut(board.BUTTON_LATCH)) def _check_buttons(self, buttons): # Check if button A was pressed if buttons == BUTTON_A: self.on_button_a() def start_loop(self): # Get the buttons that are pressed # Check current_buttons = self._pad.get_pressed() buttons = current_buttons last_read = 0 # Start a loop while True: # Only check the buttons every 1/10 a second to avoid # reading a longer press as a double press if (last_read + 0.1) < time.monotonic(): buttons = self._pad.get_pressed() last_read = time.monotonic() # If the buttons change, check the button pressed if current_buttons != buttons: self._check_buttons(buttons) current_buttons = buttons
class piperControllerPins: def __init__(self, clock_pin, clock_name, data_pin, data_name, latch_pin, latch_name): self.clock_pin = DigitalInOut(clock_pin) self.data_pin = DigitalInOut(data_pin) self.latch_pin = DigitalInOut(latch_pin) self.clock_name = clock_name self.data_name = data_name self.latch_name = latch_name self.gamepad = GamePadShift(self.clock_pin, self.data_pin, self.latch_pin, 16) def readButtons(self): #global digital_view #if (digital_view == True): # print(chr(17), self.clock_name + "|D", chr(16), end="") # print(chr(17), self.data_name + "|D", chr(16), end="") # print(chr(17), self.latch_name + "|D", chr(16), end="") send_piper_pin_state(self.clock_name, "P") send_piper_pin_state(self.data_name, "P") send_piper_pin_state(self.latch_name, "P") try: self.buttons = self.gamepad.get_pressed() except RuntimeError as e: print("Error reading controller buttons", str(e)) return self.buttons def wasPressed(self, b): if (self.buttons & b): return True else: return False
class BetterPad(): def __init__(self, clk, out, latch, buttons = {0: "b", 1: "a", 2: "start", 3: "select"}, *args, **kwargs): self._pad = GamePadShift(clk, out, latch, *args, **kwargs) self._buttons = buttons def getPressed(self): pressed = self._pad.get_pressed() output = {} for x in range(0, len(self._buttons)): output[self._buttons[x]] = pressed & 1 << x != 0 none = True for x in output: if output[x]: none = False output["none"] = none return output
pad = GamePadShift(DigitalInOut(board.BUTTON_CLOCK), DigitalInOut(board.BUTTON_OUT), DigitalInOut(board.BUTTON_LATCH)) # Button Constants BUTTON_LEFT = 128 BUTTON_UP = 64 BUTTON_DOWN = 32 BUTTON_RIGHT = 16 BUTTON_SEL = 8 BUTTON_START = 4 BUTTON_A = 2 BUTTON_B = 1 while True: buttons = pad.get_pressed() if (buttons & BUTTON_START) > 0: if show_rainbow: show_rainbow = False blackout() else: show_rainbow = True # Wait for button to be released while buttons != 0: buttons = pad.get_pressed() time.sleep(0.1) if show_rainbow: rainbow_cycle(0)
class PyBadge(PyBadgerBase): """Class that represents a single PyBadge, PyBadge LC, or EdgeBadge.""" _audio_out = audioio.AudioOut _neopixel_count = 5 def __init__(self): super().__init__() i2c = None if i2c is None: try: i2c = board.I2C() except RuntimeError: self._accelerometer = None if i2c is not None: int1 = digitalio.DigitalInOut(board.ACCELEROMETER_INTERRUPT) try: self._accelerometer = adafruit_lis3dh.LIS3DH_I2C(i2c, address=0x19, int1=int1) except ValueError: self._accelerometer = adafruit_lis3dh.LIS3DH_I2C(i2c, int1=int1) # NeoPixels self._neopixels = neopixel.NeoPixel(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._light_sensor = analogio.AnalogIn(board.A7) @property def button(self): """The buttons on the board. Example use: .. code-block:: python from adafruit_pybadger import pybadger while True: if pybadger.button.a: print("Button A") elif pybadger.button.b: print("Button B") elif pybadger.button.start: print("Button start") elif pybadger.button.select: print("Button select") """ button_values = self._buttons.get_pressed() 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, ) ])
# Enable PyBadge to write to its filesystem # if a button is pressed while rebooting # (normally the filesystem is only writeable by the host over USB) import board import digitalio import storage import time from gamepadshift import GamePadShift pad = GamePadShift(digitalio.DigitalInOut(board.BUTTON_CLOCK), digitalio.DigitalInOut(board.BUTTON_OUT), digitalio.DigitalInOut(board.BUTTON_LATCH)) time.sleep(.5) # wait a bit to read buttons if pad.get_pressed(): # CircuitPython can write to the local drive if readonly is False storage.remount("/", False) print(' Filesystem Writeable') else: print(' Filesystem ReadOnly')
class PyGamer(PyBadgerBase): """Class that represents a single PyGamer.""" _audio_out = audioio.AudioOut _neopixel_count = 5 def __init__(self): super().__init__() i2c = board.I2C() int1 = digitalio.DigitalInOut(board.ACCELEROMETER_INTERRUPT) try: self._accelerometer = adafruit_lis3dh.LIS3DH_I2C(i2c, address=0x19, int1=int1) except ValueError: self._accelerometer = adafruit_lis3dh.LIS3DH_I2C(i2c, int1=int1) self._buttons = GamePadShift( digitalio.DigitalInOut(board.BUTTON_CLOCK), digitalio.DigitalInOut(board.BUTTON_OUT), digitalio.DigitalInOut(board.BUTTON_LATCH), ) self._pygamer_joystick_x = analogio.AnalogIn(board.JOYSTICK_X) self._pygamer_joystick_y = analogio.AnalogIn(board.JOYSTICK_Y) self._light_sensor = analogio.AnalogIn(board.A7) @property def button(self): """The buttons on the board. Example use: .. code-block:: python from adafruit_pybadger import pybadger while True: if pybadger.button.a: print("Button A") elif pybadger.button.b: print("Button B") elif pybadger.button.start: print("Button start") elif pybadger.button.select: print("Button select") """ button_values = self._buttons.get_pressed() 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, x > 50000, # RIGHT y > 50000, # DOWN y < 15000, # UP x < 15000, # LEFT ) @property def joystick(self): """The joystick on the PyGamer.""" x = self._pygamer_joystick_x.value y = self._pygamer_joystick_y.value return x, y
for x in range(1, 5): castle[x, 0] = 4 # top castle[x, 4] = 10 # bottom # left/ right walls for y in range(1, 4): castle[0, y] = 6 # left castle[5, y] = 8 # right # floor for x in range(1, 5): for y in range(1, 4): castle[x, y] = 7 # floor # put the sprite somewhere in the castle sprite.x = 110 sprite.y = 70 # Initialize controller input joystick_x = analogio.AnalogIn(board.JOYSTICK_X) joystick_y = analogio.AnalogIn(board.JOYSTICK_Y) pad = GamePadShift(digitalio.DigitalInOut(board.BUTTON_CLOCK), digitalio.DigitalInOut(board.BUTTON_OUT), digitalio.DigitalInOut(board.BUTTON_LATCH)) # Add the Group to the Display while not pad.get_pressed(): sprite.x += int((joystick_x.value - 32767) / 5000) sprite.y += int((joystick_y.value - 32767) / 5000) display.show(group) time.sleep(0.1)
# setup for PyBadge buttons BUTTON_LEFT = const(128) BUTTON_UP = const(64) BUTTON_DOWN = const(32) BUTTON_RIGHT = const(16) BUTTON_SEL = const(8) BUTTON_START = const(4) BUTTON_A = const(2) BUTTON_B = const(1) pad = GamePadShift(digitalio.DigitalInOut(board.BUTTON_CLOCK), digitalio.DigitalInOut(board.BUTTON_OUT), digitalio.DigitalInOut(board.BUTTON_LATCH)) current_buttons = pad.get_pressed() last_read = 0 # enables speaker speakerEnable = digitalio.DigitalInOut(board.SPEAKER_ENABLE) speakerEnable.switch_to_output(value=True) # Sprite cell values EMPTY = 0 BLINKA_1 = 1 BLINKA_2 = 2 SPARKY = 3 HEART = 4 JUMP_1 = 5 JUMP_2 = 6
class PyBadger: """PyBadger class.""" # Button Constants BUTTON_LEFT = const(128) BUTTON_UP = const(64) BUTTON_DOWN = const(32) BUTTON_RIGHT = const(16) BUTTON_SELECT = const(8) BUTTON_START = const(4) BUTTON_A = const(2) BUTTON_B = const(1) def __init__(self, i2c=None): # Accelerometer if i2c is None: i2c = board.I2C() int1 = digitalio.DigitalInOut(board.ACCELEROMETER_INTERRUPT) try: self._accelerometer = adafruit_lis3dh.LIS3DH_I2C(i2c, address=0x19, int1=int1) except ValueError: self._accelerometer = adafruit_lis3dh.LIS3DH_I2C(i2c, int1=int1) # Buttons self._buttons = GamePadShift( digitalio.DigitalInOut(board.BUTTON_CLOCK), digitalio.DigitalInOut(board.BUTTON_OUT), digitalio.DigitalInOut(board.BUTTON_LATCH)) # Display self.display = board.DISPLAY # Light sensor self._light_sensor = analogio.AnalogIn(board.A7) # PyGamer joystick if hasattr(board, "JOYSTICK_X"): self._pygamer_joystick_x = analogio.AnalogIn(board.JOYSTICK_X) self._pygamer_joystick_y = analogio.AnalogIn(board.JOYSTICK_Y) # NeoPixels # Count is hardcoded - should be based on board ID, currently no board info for PyBadge LC neopixel_count = 5 self._neopixels = neopixel.NeoPixel(board.NEOPIXEL, neopixel_count, pixel_order=neopixel.GRB) # Auto dim display based on movement self._last_accelerometer = None self._start_time = time.monotonic() # Define audio: self._speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE) self._speaker_enable.switch_to_output(value=False) self._sample = None self._sine_wave = None self._sine_wave_sample = None def _check_for_movement(self, movement_threshold=10): """Checks to see if board is moving. Used to auto-dim display when not moving.""" current_accelerometer = self.acceleration if self._last_accelerometer is None: self._last_accelerometer = current_accelerometer return False acceleration_delta = sum([ abs(self._last_accelerometer[n] - current_accelerometer[n]) for n in range(3) ]) self._last_accelerometer = current_accelerometer return acceleration_delta > movement_threshold def auto_dim_display(self, delay=5.0, movement_threshold=10): """Auto-dim the display when board is not moving. :param int delay: Time in seconds before display auto-dims after movement has ceased. :param int movement_threshold: Threshold required for movement to be considered stopped. Change to increase or decrease sensitivity. """ if not self._check_for_movement(movement_threshold=movement_threshold): current_time = time.monotonic() if current_time - self._start_time > delay: self.display.brightness = 0.1 self._start_time = current_time else: self.display.brightness = 1 @property def pixels(self): """Sequence like object representing the NeoPixels on the board.""" return self._neopixels @property def joystick(self): """The joystick on the PyGamer.""" if hasattr(board, "JOYSTICK_X"): x = self._pygamer_joystick_x.value y = self._pygamer_joystick_y.value return x, y raise RuntimeError("This board does not have a built in joystick.") @property def button(self): """The buttons on the board. Example use: .. code-block:: python from adafruit_pybadger import PyBadger pybadger = PyBadger() while True: if pybadger.button.a: print("Button A") elif pybadger.button.b: print("Button B") elif pybadger.button.start: print("Button start") elif pybadger.button.select: print("Button select") """ button_values = self._buttons.get_pressed() return Buttons(*[ button_values & button for button in (PyBadger.BUTTON_B, PyBadger.BUTTON_A, PyBadger.BUTTON_START, PyBadger.BUTTON_SELECT, PyBadger.BUTTON_RIGHT, PyBadger.BUTTON_DOWN, PyBadger.BUTTON_UP, PyBadger.BUTTON_LEFT) ]) @property def light(self): """Light sensor data.""" return self._light_sensor.value @property def acceleration(self): """Accelerometer data.""" return self._accelerometer.acceleration @property def brightness(self): """Display brightness.""" return self.display.brightness @brightness.setter def brightness(self, value): self.display.brightness = value def show_business_card(self, image_name=None, dwell=20): """Display a bitmap image and a text string, such as a personal image and email address. CURRENTLY ONLY DISPLAYS BITMAP IMAGE. Text string to be added. :param str image_name: The name of the bitmap image including .bmp, e.g. ``"Blinka.bmp"``. :param int dwell: The amount of time in seconds to display the business card. """ business_card_splash = displayio.Group(max_size=30) self.display.show(business_card_splash) with open(image_name, "rb") as file_name: on_disk_bitmap = displayio.OnDiskBitmap(file_name) face_image = displayio.TileGrid( on_disk_bitmap, pixel_shader=displayio.ColorConverter()) business_card_splash.append(face_image) # Wait for the image to load. self.display.wait_for_frame() time.sleep(dwell) # pylint: disable=too-many-locals def show_badge(self, *, background_color=0xFF0000, foreground_color=0xFFFFFF, background_text_color=0xFFFFFF, foreground_text_color=0x000000, hello_font=terminalio.FONT, hello_scale=1, hello_string="HELLO", my_name_is_font=terminalio.FONT, my_name_is_scale=1, my_name_is_string="MY NAME IS", name_font=terminalio.FONT, name_scale=1, name_string="Blinka"): """Create a "Hello My Name is"-style badge. :param background_color: The color of the background. Defaults to 0xFF0000. :param foreground_color: The color of the foreground rectangle. Defaults to 0xFFFFFF. :param background_text_color: The color of the "HELLO MY NAME IS" text. Defaults to 0xFFFFFF. :param foreground_text_color: The color of the name text. Defaults to 0x000000. :param hello_font: The font for the "HELLO" string. Defaults to ``terminalio.FONT``. :param hello_scale: The size scale of the "HELLO" string. Defaults to 1. :param hello_string: The first string of the badge. Defaults to "HELLO". :param my_name_is_font: The font for the "MY NAME IS" string. Defaults to ``terminalio.FONT``. :param my_name_is_scale: The size scale of the "MY NAME IS" string. Defaults to 1. :param my_name_is_string: The second string of the badge. Defaults to "MY NAME IS". :param name_font: The font for the name string. Defaults to ``terminalio.FONT``. :param name_scale: The size scale of the name string. Defaults to 1. :param name_string: The third string of the badge - change to be your name. Defaults to "Blinka". """ # Make the Display Background splash = displayio.Group(max_size=20) color_bitmap = displayio.Bitmap(self.display.width, self.display.height, 1) color_palette = displayio.Palette(1) color_palette[0] = background_color bg_sprite = displayio.TileGrid(color_bitmap, pixel_shader=color_palette, x=0, y=0) splash.append(bg_sprite) # Draw a Foreground Rectangle where the name goes # x, y, width, height rect = Rect(0, (int(self.display.height * 0.4)), self.display.width, (int(self.display.height * 0.5)), fill=foreground_color) splash.append(rect) hello_scale = hello_scale hello_group = displayio.Group(scale=hello_scale) # Setup and Center the Hello Label hello_label = Label(font=hello_font, text=hello_string) (_, _, width, height) = hello_label.bounding_box hello_label.x = ((self.display.width // (2 * hello_scale)) - width // 2) hello_label.y = int(height // (1.2 * hello_scale)) hello_label.color = background_text_color hello_group.append(hello_label) my_name_is_scale = my_name_is_scale my_name_is_group = displayio.Group(scale=my_name_is_scale) # Setup and Center the "My Name Is" Label my_name_is_label = Label(font=my_name_is_font, text=my_name_is_string) (_, _, width, height) = my_name_is_label.bounding_box my_name_is_label.x = ((self.display.width // (2 * my_name_is_scale)) - width // 2) my_name_is_label.y = int(height // (0.42 * my_name_is_scale)) my_name_is_label.color = background_text_color my_name_is_group.append(my_name_is_label) name_scale = name_scale name_group = displayio.Group(scale=name_scale) # Setup and Center the Name Label name_label = Label(font=name_font, text=name_string) (_, _, width, height) = name_label.bounding_box name_label.x = ((self.display.width // (2 * name_scale)) - width // 2) name_label.y = int(height // (0.17 * name_scale)) name_label.color = foreground_text_color name_group.append(name_label) group = displayio.Group() group.append(splash) group.append(hello_group) group.append(my_name_is_group) group.append(name_group) self.display.show(group) @staticmethod def bitmap_qr(matrix): """The QR code bitmap.""" border_pixels = 2 bitmap = displayio.Bitmap(matrix.width + 2 * border_pixels, matrix.height + 2 * border_pixels, 2) for y in range(matrix.height): for x in range(matrix.width): if matrix[x, y]: bitmap[x + border_pixels, y + border_pixels] = 1 else: bitmap[x + border_pixels, y + border_pixels] = 0 return bitmap def show_qr_code(self, data=b'https://circuitpython.org', dwell=20): """Generate a QR code and display it for ``dwell`` seconds. :param bytearray data: A bytearray of data for the QR code :param int dwell: The amount of time in seconds to display the QR code """ qr_code = adafruit_miniqr.QRCode(qr_type=3, error_correct=adafruit_miniqr.L) qr_code.add_data(data) qr_code.make() qr_bitmap = self.bitmap_qr(qr_code.matrix) palette = displayio.Palette(2) palette[0] = 0xFFFFFF palette[1] = 0x000000 qr_code_scale = min(self.display.width // qr_bitmap.width, self.display.height // qr_bitmap.height) qr_position_x = int( ((self.display.width / qr_code_scale) - qr_bitmap.width) / 2) qr_position_y = int( ((self.display.height / qr_code_scale) - qr_bitmap.height) / 2) qr_img = displayio.TileGrid(qr_bitmap, pixel_shader=palette, x=qr_position_x, y=qr_position_y) qr_code = displayio.Group(scale=qr_code_scale) qr_code.append(qr_img) self.display.show(qr_code) time.sleep(dwell) @staticmethod def _sine_sample(length): tone_volume = (2**15) - 1 shift = 2**15 for i in range(length): yield int(tone_volume * math.sin(2 * math.pi * (i / length)) + shift) def _generate_sample(self, length=100): if self._sample is not None: return self._sine_wave = array.array("H", PyBadger._sine_sample(length)) self._sample = audioio.AudioOut(board.SPEAKER) self._sine_wave_sample = audioio.RawSample(self._sine_wave) def play_tone(self, frequency, duration): """ Produce a tone using the speaker. Try changing frequency to change the pitch of the tone. :param int frequency: The frequency of the tone in Hz :param float duration: The duration of the tone in seconds """ # Play a tone of the specified frequency (hz). self.start_tone(frequency) time.sleep(duration) self.stop_tone() def start_tone(self, frequency): """ Produce a tone using the speaker. Try changing frequency to change the pitch of the tone. :param int frequency: The frequency of the tone in Hz """ self._speaker_enable.value = True length = 100 if length * frequency > 350000: length = 350000 // frequency self._generate_sample(length) # Start playing a tone of the specified frequency (hz). self._sine_wave_sample.sample_rate = int( len(self._sine_wave) * frequency) if not self._sample.playing: self._sample.play(self._sine_wave_sample, loop=True) def stop_tone(self): """ Use with start_tone to stop the tone produced. """ # Stop playing any tones. if self._sample is not None and self._sample.playing: self._sample.stop() self._sample.deinit() self._sample = None self._speaker_enable.value = False def play_file(self, file_name): """ Play a .wav file using the onboard speaker. :param file_name: The name of your .wav file in quotation marks including .wav """ # Play a specified file. self.stop_tone() self._speaker_enable.value = True with audioio.AudioOut(board.SPEAKER) as audio: wavefile = audioio.WaveFile(open(file_name, "rb")) audio.play(wavefile) while audio.playing: pass self._speaker_enable.value = False
# draw hit point bar hit_point_bar = Rect(3, 27, MAX_HIT_POINT_BAR_WIDTH, 3, fill=GREEN) group.append(hit_point_bar) # initialize hit point text font_name = bitmap_font.load_font(FONTNAME) font_name.load_glyphs("TEST".encode('utf-8')) hit_point_label = Label(font_name, text="ELF", line_spacing=0.75) (x, y, w, h) = hit_point_label.bounding_box hit_point_label.y = 25 # display.show(hit_point_label) # group.append(hit_point_label) display.show(group) current_buttons = pad.get_pressed() last_read = 0 max_hit_points = 25 current_hit_points = max_hit_points source_index = 0 hit_point_level = 1 while True: index = source_index % (hit_point_level * 6) if (hit_point_level - 1) * 6 <= index < hit_point_level * 6: sprite[0] = index time.sleep(0.05) source_index += 1 # reading buttons too fast returns 0 if (last_read + 0.1) < time.monotonic(): buttons = pad.get_pressed()
class CursorManager: """Simple interaction user interface interaction for Adafruit_CursorControl. :param adafruit_cursorcontrol cursor: The cursor object we are using. """ def __init__(self, cursor): self._cursor = cursor self._is_clicked = False self._init_hardware() def __enter__(self): return self def __exit__(self, exception_type, exception_value, traceback): self.deinit() def deinit(self): """Deinitializes a CursorManager object.""" self._is_deinited() self._pad.deinit() self._cursor.deinit() self._cursor = None def _is_deinited(self): """Checks if CursorManager object has been deinitd.""" if self._cursor is None: raise ValueError( "CursorManager object has been deinitialized and can no longer " "be used. Create a new CursorManager object." ) def _init_hardware(self): """Initializes PyBadge or PyGamer hardware.""" if hasattr(board, "BUTTON_CLOCK") and not hasattr(board, "JOYSTICK_X"): self._pad_btns = { "btn_left": PYBADGE_BUTTON_LEFT, "btn_right": PYBADGE_BUTTON_RIGHT, "btn_up": PYBADGE_BUTTON_UP, "btn_down": PYBADGE_BUTTON_DOWN, "btn_a": PYBADGE_BUTTON_A, } elif hasattr(board, "JOYSTICK_X"): self._joystick_x = analogio.AnalogIn(board.JOYSTICK_X) self._joystick_y = analogio.AnalogIn(board.JOYSTICK_Y) self._pad_btns = {"btn_a": PYBADGE_BUTTON_A} # Sample the center points of the joystick self._center_x = self._joystick_x.value self._center_y = self._joystick_y.value else: raise AttributeError( "Board must have a D-Pad or Joystick for use with CursorManager!" ) self._pad = GamePadShift( digitalio.DigitalInOut(board.BUTTON_CLOCK), digitalio.DigitalInOut(board.BUTTON_OUT), digitalio.DigitalInOut(board.BUTTON_LATCH), ) @property def is_clicked(self): """Returns True if the cursor button was pressed during previous call to update() """ return self._is_clicked def update(self): """Updates the cursor object.""" pressed = self._pad.get_pressed() self._check_cursor_movement(pressed) if self._is_clicked: self._is_clicked = False elif pressed & self._pad_btns["btn_a"]: self._is_clicked = True def _read_joystick_x(self, samples=3): """Read the X analog joystick on the PyGamer. :param int samples: How many samples to read and average. """ reading = 0 # pylint: disable=unused-variable if hasattr(board, "JOYSTICK_X"): for sample in range(0, samples): reading += self._joystick_x.value reading /= samples return reading def _read_joystick_y(self, samples=3): """Read the Y analog joystick on the PyGamer. :param int samples: How many samples to read and average. """ reading = 0 # pylint: disable=unused-variable if hasattr(board, "JOYSTICK_Y"): for sample in range(0, samples): reading += self._joystick_y.value reading /= samples return reading def _check_cursor_movement(self, pressed=None): """Checks the PyBadge D-Pad or the PyGamer's Joystick for movement. :param int pressed: 8-bit number with bits that correspond to buttons which have been pressed down since the last call to get_pressed(). """ if hasattr(board, "BUTTON_CLOCK") and not hasattr(board, "JOYSTICK_X"): if pressed & self._pad_btns["btn_right"]: self._cursor.x += self._cursor.speed elif pressed & self._pad_btns["btn_left"]: self._cursor.x -= self._cursor.speed if pressed & self._pad_btns["btn_up"]: self._cursor.y -= self._cursor.speed elif pressed & self._pad_btns["btn_down"]: self._cursor.y += self._cursor.speed elif hasattr(board, "JOYSTICK_X"): joy_x = self._read_joystick_x() joy_y = self._read_joystick_y() if joy_x > self._center_x + 1000: self._cursor.x += self._cursor.speed elif joy_x < self._center_x - 1000: self._cursor.x -= self._cursor.speed if joy_y > self._center_y + 1000: self._cursor.y += self._cursor.speed elif joy_y < self._center_y - 1000: self._cursor.y -= self._cursor.speed else: raise AttributeError( "Board must have a D-Pad or Joystick for use with CursorManager!" )
class Button: """Class to read Buttons on AdaFruit EDGE Badge.""" """ TODO: Need to debounce all the buttons in here, and also detect chords. Chords can be captured as maximum value during press. Instead of sleeping, should set a flag meaning 'button(s) are down' And then another flag when they are all stable and up. Use timestamps instead of delays so maybe things can continue to happen. This requires some sort of threading or interrupts? Or maybe it spins inside here? Would like to have a button interrupt, especially for start/preset() Need a debounce button method for all buttons """ # Button Constants BUTTON_LEFT = const(128) BUTTON_UP = const(64) BUTTON_DOWN = const(32) BUTTON_RIGHT = const(16) BUTTON_SELECT = const(8) BUTTON_START = const(4) BUTTON_A = const(2) BUTTON_B = const(1) def __init__(self, lights=None, i2c=None): # Buttons self._buttons = GamePadShift(digitalio.DigitalInOut(board.BUTTON_CLOCK), digitalio.DigitalInOut(board.BUTTON_OUT), digitalio.DigitalInOut(board.BUTTON_LATCH)) self.button_values = self._buttons.get_pressed() self.lights = lights def scan(self): self.button_values = self._buttons.get_pressed() @property def left(self): return self.button_values & self.BUTTON_LEFT @property def up(self): return self.button_values & self.BUTTON_UP @property def down(self): return self.button_values & self.BUTTON_DOWN @property def right(self): return self.button_values & self.BUTTON_RIGHT @property def select(self): return self.button_values & self.BUTTON_SELECT @property def start(self): return self.button_values & self.BUTTON_START @property def a(self): return self.button_values & self.BUTTON_A @property def b(self): return self.button_values & self.BUTTON_B def set_light_color(self, color_attr): if self.lights is not None: lights.pixels[2] = getattr(self.lights, color_attr) def debounce_select(self): pressed = False if self.select: pressed = True lights.pixels[2] = lights.pale_green while self.select: self.set_light_color('pale_blue') time.sleep(0.05) self.scan() else: lights.pixels[2] = lights.black return pressed
uart = busio.UART(TX, RX, baudrate=9600, timeout=30) gps = adafruit_gps.GPS(uart, debug=False) gps.send_command(b'PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0') gps.send_command(b'PMTK220,1000') pad = GamePadShift(digitalio.DigitalInOut(board.BUTTON_CLOCK), digitalio.DigitalInOut(board.BUTTON_OUT), digitalio.DigitalInOut(board.BUTTON_LATCH)) joystick_x = analogio.AnalogIn(board.JOYSTICK_X) joystick_y = analogio.AnalogIn(board.JOYSTICK_Y) pressed = pad.get_pressed() select = 0 b = 0 last_print = time.monotonic() a = 0 homelat = 38.888 homelon = -77.115 def haversine(lat1, lon1, lat2, lon2): degree_to_rad = float(pi / 180.0) d_lat = (lat2 - lat1) * degree_to_rad
# Display image or histogram t6 = time.monotonic() # Time marker: Display Image if display_image: update_image_frame(selfie=SELFIE) else: update_histo_frame() # If alarm threshold is reached, flash NeoPixels and play alarm tone if v_max >= ALARM_C: pixels.fill(RED) play_tone(880, 0.015) # A5 pixels.fill(BLACK) # See if a panel button is pressed buttons = panel.get_pressed() if buttons & BUTTON_A: # Toggle display hold (shutter) play_tone(1319, 0.030) # E6 display_hold = not display_hold while buttons & BUTTON_A: buttons = panel.get_pressed() time.sleep(0.1) if buttons & BUTTON_B: # Toggle image/histogram mode (display image) play_tone(659, 0.030) # E5 display_image = not display_image while buttons & BUTTON_B: buttons = panel.get_pressed() time.sleep(0.1)