Last active
February 6, 2024 23:46
-
-
Save MTN-RowinAndruscavage/a8037f870cefbbedc171b1bcc2d949f0 to your computer and use it in GitHub Desktop.
DeskPi PicoMate Party Parrot
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Party Parrot adapted to DeskPi PicoMate | |
| # from https://learn.adafruit.com/iot-twitter-listener-party-parrot/coding-the-iot-party-parrot | |
| import os, microcontroller, board, time | |
| import busio, digitalio, displayio, rotaryio, terminalio, asyncio | |
| import adafruit_imageload | |
| from adafruit_display_text import label | |
| import adafruit_displayio_ssd1306 | |
| from adafruit_ssd1306 import SSD1306_I2C | |
| led = digitalio.DigitalInOut(board.LED) | |
| led.direction = digitalio.Direction.OUTPUT | |
| encoder = rotaryio.IncrementalEncoder(board.GP7, board.GP6) | |
| last_position = encoder.position | |
| switch = digitalio.DigitalInOut(board.GP26) | |
| switch.direction = digitalio.Direction.INPUT | |
| switch.pull = digitalio.Pull.DOWN | |
| switch_state = switch.value | |
| p = 0 # index for tilegrid | |
| pos = encoder.position # rotary encoder position | |
| # i2c display setup | |
| displayio.release_displays() | |
| oled_reset = board.GP9 | |
| i2c = busio.I2C(board.GP17, board.GP16) | |
| display_bus = displayio.I2CDisplay(i2c, device_address=0x3C, reset=oled_reset) | |
| WIDTH = 128 | |
| HEIGHT = 64 | |
| offset_y = 5 | |
| display = adafruit_displayio_ssd1306.SSD1306(display_bus, width=WIDTH, height=HEIGHT) | |
| # default display group | |
| splash = displayio.Group() | |
| display.root_group = splash | |
| ssid_text = f"{os.getenv('CIRCUITPY_WIFI_SSID')}" | |
| ssid_text_area = label.Label( | |
| terminalio.FONT, text=ssid_text, color=0xFFFFFF, x=0, y=offset_y+15 | |
| ) | |
| splash.append(ssid_text_area) | |
| rotary_text = f"Rotary: {pos}" | |
| rotary_text_area = label.Label( | |
| terminalio.FONT, text=rotary_text, color=0xFFFFFF, x=0, y=offset_y+30 | |
| ) | |
| splash.append(rotary_text_area) | |
| parrot_group = displayio.Group() | |
| # bitmap from https://github.com/adafruit/Adafruit_Learning_System_Guides/tree/main/PicoW_CircuitPython_HTTP_Server | |
| parrot_bit, parrot_pal = adafruit_imageload.load("/partyParrots64.bmp", | |
| bitmap=displayio.Bitmap, | |
| palette=displayio.Palette) | |
| parrot_grid = displayio.TileGrid(parrot_bit, pixel_shader=parrot_pal, | |
| width=1, height=1, | |
| tile_height=64, tile_width=64, | |
| default_tile=1, | |
| x=32, y=0) | |
| parrot_group.append(parrot_grid) | |
| pos_text = f"{p}" | |
| pos_text_area = label.Label( | |
| terminalio.FONT, text=pos_text, color=0xFFFFFF, x=0, y=offset_y+50 | |
| ) | |
| parrot_group.append(pos_text_area) | |
| # pause animation a second after user input | |
| manual_clock = time.monotonic() - 1 | |
| parrot = True # display parrot or splash screen | |
| def display_Update(p): | |
| global display, parrot, parrot_grid, parrot_group, rotary_text_area | |
| if parrot: | |
| # switch to party parrot display group | |
| display.root_group = parrot_group | |
| # cycle the party parrot animation | |
| parrot_grid[0] = p | |
| else: | |
| # if it isn't a party show default splash with info | |
| rotary_text_area.text = f"Rotary: {pos}" | |
| display.root_group = splash | |
| async def auto_Time(): | |
| global p, pos, manual_clock, parrot | |
| delay = 0.1 | |
| while True: | |
| if parrot: | |
| if manual_clock > time.monotonic(): | |
| # rotary encoder position adjusts party speed | |
| delay = 0.1 * pow(1.1,pos) | |
| p = -pos # rotate parrot in same direction as encoder | |
| if pos < 1: | |
| p = (p + 1) % 10 # counterclockwise party | |
| else: | |
| p = (p - 1) % 10 # clockwise party | |
| display_Update(p) | |
| await asyncio.sleep(delay) | |
| async def check_Rotary(): | |
| global pos, encoder, parrot, last_position, manual_clock, switch, switch_state | |
| while True: | |
| pos = encoder.position | |
| if last_position is None or pos != last_position: | |
| print(f"Rotary: {pos}") | |
| # pause animation a second after user input | |
| manual_clock = time.monotonic() + 1 | |
| pos_text_area.text = ('<' if pos < 1 else '>') | |
| last_position = pos | |
| if switch_state != switch.value: | |
| switch_state = switch.value | |
| if switch.value: | |
| parrot = not parrot | |
| print('parrot is ' + ('ON' if parrot else 'OFF')) | |
| await asyncio.sleep(0.1) | |
| async def main(): | |
| tasks = [] | |
| tasks.append(asyncio.create_task(check_Rotary())) | |
| tasks.append(asyncio.create_task(auto_Time())) | |
| await asyncio.gather(*tasks) | |
| if __name__ =='__main__': | |
| asyncio.run(main()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment