code.py
1 # SPDX-FileCopyrightText: 2022 Dan Halbert for Adafruit Industries 2 # 3 # SPDX-License-Identifier: MIT 4 5 import asyncio 6 7 import board 8 import keypad 9 import neopixel 10 from rainbowio import colorwheel 11 12 pixel_pin = board.A0 13 num_pixels = 24 14 15 pixels = neopixel.NeoPixel(pixel_pin, num_pixels, brightness=0.03, auto_write=False) 16 17 18 class Controls: 19 def __init__(self): 20 self.reverse = False 21 self.wait = 0.0 22 23 24 async def rainbow_cycle(controls): 25 while True: 26 # Increment by 2 instead of 1 to speed the cycle up a bit. 27 for j in range(255, -1, -2) if controls.reverse else range(0, 256, 2): 28 for i in range(num_pixels): 29 rc_index = (i * 256 // num_pixels) + j 30 pixels[i] = colorwheel(rc_index & 255) 31 pixels.show() 32 await asyncio.sleep(controls.wait) 33 34 35 async def monitor_buttons(reverse_pin, slower_pin, faster_pin, controls): 36 """Monitor buttons that reverse direction and change animation speed. 37 Assume buttons are active low. 38 """ 39 with keypad.Keys( 40 (reverse_pin, slower_pin, faster_pin), value_when_pressed=False, pull=True 41 ) as keys: 42 while True: 43 key_event = keys.events.get() 44 if key_event and key_event.pressed: 45 key_number = key_event.key_number 46 if key_number == 0: 47 controls.reverse = not controls.reverse 48 elif key_number == 1: 49 # Lengthen the interval. 50 controls.wait = controls.wait + 0.001 51 elif key_number == 2: 52 # Shorten the interval. 53 controls.wait = max(0.0, controls.wait - 0.001) 54 # Let another task run. 55 await asyncio.sleep(0) 56 57 58 async def main(): 59 controls = Controls() 60 61 buttons_task = asyncio.create_task( 62 monitor_buttons(board.A1, board.A2, board.A3, controls) 63 ) 64 animation_task = asyncio.create_task(rainbow_cycle(controls)) 65 66 # This will run forever, because no tasks ever finish. 67 await asyncio.gather(buttons_task, animation_task) 68 69 70 asyncio.run(main())