Skip to content

Commit 45aaacc

Browse files
authored
Merge pull request #2129 from kattni/asyncio-template-code
Add asyncio template code.
2 parents 913ca10 + 37eb221 commit 45aaacc

File tree

1 file changed

+94
-0
lines changed
  • CircuitPython_Templates/asyncio

1 file changed

+94
-0
lines changed
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2022 Dan Halbert for Adafruit Industries
2+
# SPDX-FileCopyrightText: Copyright (c) 2022 Kattni Rembor for Adafruit Industries
3+
#
4+
# SPDX-License-Identifier: MIT
5+
"""
6+
CircuitPython asyncio example for two NeoPixel rings and one button.
7+
REMOVE THIS LINE AND THE REST OF THIS DOCSTRING BEFORE SUBMITTING TO LEARN
8+
THERE ARE TWO POSSIBLE THINGS IN THE CODE TO UPDATE.
9+
10+
One: Update BUTTON to the pin that matches the pin to which the button is connected.
11+
12+
For example, on the QT Py RP2040, you would leave it as BUTTON to use the built-in Boot button.
13+
On the FunHouse, you would update BUTTON to BUTTON_UP to use the built-in up button.
14+
On the Feather M4 Express, you would wire the external button to A0, and update BUTTON to A0.
15+
16+
Two: THIS IS ONLY NECESSARY IF THE BUILT-IN BUTTON IS ACTIVE HIGH. For example the built-in
17+
buttons on the Circuit Playground Bluefruit and the MagTag are active high.
18+
If your button is ACTIVE HIGH, under "async def monitor_button(button, animation_controls)",
19+
update the following line of code:
20+
with keypad.Keys((button,), value_when_pressed=False, pull=True) as key:
21+
To the following:
22+
with keypad.Keys((button,), value_when_pressed=True, pull=True) as key:
23+
"""
24+
import asyncio
25+
import board
26+
import neopixel
27+
import keypad
28+
from rainbowio import colorwheel
29+
30+
button_pin = board.BUTTON # The pin the button is connected to.
31+
num_pixels = 16 # The number of NeoPixels on a single ring.
32+
brightness = 0.2 # The LED brightness.
33+
34+
# Set up NeoPixel rings.
35+
ring_one = neopixel.NeoPixel(board.A1, num_pixels, brightness=brightness, auto_write=False)
36+
ring_two = neopixel.NeoPixel(board.A2, num_pixels, brightness=brightness, auto_write=False)
37+
38+
39+
class AnimationControls:
40+
"""The controls to allow you to vary the rainbow and blink animations."""
41+
def __init__(self):
42+
self.reverse = False
43+
self.wait = 0.0
44+
self.delay = 0.5
45+
46+
47+
async def rainbow_cycle(animation_controls):
48+
"""Rainbow cycle animation on ring one."""
49+
while True:
50+
for j in range(255, -1, -1) if animation_controls.reverse else range(0, 256, 1):
51+
for i in range(num_pixels):
52+
rc_index = (i * 256 // num_pixels) + j
53+
ring_one[i] = colorwheel(rc_index & 255)
54+
ring_one.show()
55+
await asyncio.sleep(animation_controls.wait)
56+
57+
58+
async def blink(animation_controls):
59+
"""Blink animation on ring two."""
60+
while True:
61+
ring_two[:] = [(0, 0, abs(ring_two[0][2] - 255))] * num_pixels
62+
await asyncio.sleep(animation_controls.delay)
63+
ring_two.show()
64+
await asyncio.sleep(animation_controls.wait)
65+
66+
67+
async def monitor_button(button, animation_controls):
68+
"""Monitor button that reverses rainbow direction and changes blink speed.
69+
Assume button is active low.
70+
"""
71+
with keypad.Keys((button,), value_when_pressed=False, pull=True) as key:
72+
while True:
73+
key_event = key.events.get()
74+
if key_event:
75+
if key_event.pressed:
76+
animation_controls.reverse = True
77+
animation_controls.delay = 0.1
78+
elif key_event.released:
79+
animation_controls.reverse = False
80+
animation_controls.delay = 0.5
81+
# Let another task run.
82+
await asyncio.sleep(0)
83+
84+
85+
async def main():
86+
animation_controls = AnimationControls()
87+
buttons_task = asyncio.create_task(monitor_button(button_pin, animation_controls))
88+
animation_task = asyncio.create_task(rainbow_cycle(animation_controls))
89+
blink_task = asyncio.create_task(blink(animation_controls))
90+
91+
# This will run forever, because no tasks ever finish.
92+
await asyncio.gather(buttons_task, animation_task, blink_task)
93+
94+
asyncio.run(main())

0 commit comments

Comments
 (0)