在 circuitpython 中使用 asyncio 方式控制多路 neopixel

Adafruit CircuitPython相关
MicroPython重要分支
回复
头像
shaoziyang
帖子: 3917
注册时间: 2019年 10月 21日 13:48

在 circuitpython 中使用 asyncio 方式控制多路 neopixel

#1

帖子 shaoziyang »

这是 circuitpython 中关于 asyncio 多任务的一个例子

代码: 全选

# SPDX-FileCopyrightText: 2022 Dan Halbert for Adafruit Industries
#
# SPDX-License-Identifier: MIT

import asyncio

import board
import keypad
import neopixel
from rainbowio import colorwheel

pixel_pin = board.A0
num_pixels = 24

pixels = neopixel.NeoPixel(pixel_pin, num_pixels, brightness=0.03, auto_write=False)


class Controls:
    def __init__(self):
        self.reverse = False
        self.wait = 0.0


async def rainbow_cycle(controls):
    while True:
        # Increment by 2 instead of 1 to speed the cycle up a bit.
        for j in range(255, -1, -2) if controls.reverse else range(0, 256, 2):
            for i in range(num_pixels):
                rc_index = (i * 256 // num_pixels) + j
                pixels[i] = colorwheel(rc_index & 255)
            pixels.show()
            await asyncio.sleep(controls.wait)


async def monitor_buttons(reverse_pin, slower_pin, faster_pin, controls):
    """Monitor buttons that reverse direction and change animation speed.
    Assume buttons are active low.
    """
    with keypad.Keys(
        (reverse_pin, slower_pin, faster_pin), value_when_pressed=False, pull=True
    ) as keys:
        while True:
            key_event = keys.events.get()
            if key_event and key_event.pressed:
                key_number = key_event.key_number
                if key_number == 0:
                    controls.reverse = not controls.reverse
                elif key_number == 1:
                    # Lengthen the interval.
                    controls.wait = controls.wait + 0.001
                elif key_number == 2:
                    # Shorten the interval.
                    controls.wait = max(0.0, controls.wait - 0.001)
            # Let another task run.
            await asyncio.sleep(0)


async def main():
    controls = Controls()

    buttons_task = asyncio.create_task(
        monitor_buttons(board.A1, board.A2, board.A3, controls)
    )
    animation_task = asyncio.create_task(rainbow_cycle(controls))

    # This will run forever, because no tasks ever finish.
    await asyncio.gather(buttons_task, animation_task)


asyncio.run(main())

头像
shaoziyang
帖子: 3917
注册时间: 2019年 10月 21日 13:48

Re: 在 circuitpython 中使用 asyncio 方式控制多路 neopixel

#2

帖子 shaoziyang »

注意需要更新 circuitpython 到 7.1.0 或更高版本,才能支持 asyncio。

回复

  • 随机主题
    回复总数
    阅读次数
    最新文章