MicroPython/RP2350ZERO/utils/led.py

127 lines
4.2 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import utime
from machine import Pin
from neopixel import NeoPixel
class WS2812:
"""WS2812可编程 RGB LED"""
def __init__(self, pin=16, led_beads=1):
"""
:param pin: 引脚编号RP2350ZERO板载WS2812使用引脚16
:param led_beads: LED灯珠数
"""
if not isinstance(led_beads, int):
raise TypeError("led_beads数据类型应为整数")
if not led_beads >= 1:
raise ValueError("led_beads应大于等于1")
self.led_beads = led_beads
# 尝试初始化LED
try:
self.led = NeoPixel(Pin(pin, Pin.OUT), self.led_beads)
except Exception as exception:
raise RuntimeError(f"初始化LED发生异常{str(exception)}") from exception
def set_colors(self, colors):
"""
设置灯珠颜色
:param colors: 包含每颗灯珠RGB的颜色列表
"""
if not isinstance(colors, list):
raise TypeError("colors数据类型应为列表")
if len(colors) != self.led_beads:
raise ValueError("colors列表长度应与LED灯珠数一致")
for bead_idx, bead_color in enumerate(colors):
if not isinstance(bead_color, tuple):
raise TypeError("灯珠颜色数据类型应为元组")
if len(bead_color) != 3:
raise ValueError("灯珠颜色长度应为3")
for channel_idx, channel_value in enumerate(bead_color):
if not isinstance(channel_value, int):
raise TypeError("通道数据数据类型应为整数")
if not 0 <= channel_value <= 255:
raise ValueError("通道数据应在0255范围内")
for bead_idx, bead_color in enumerate(colors):
# 将RGB转为GRB并设置灯珠颜色
self.led[bead_idx] = (bead_color[1], bead_color[0], bead_color[2])
# LED刷新
self.led.write()
def iridesce(self, hue_offset=20):
"""通过HSV颜色空间生成渐变炫彩效果
:param hue_offset: 色相偏移角度
"""
if not isinstance(hue_offset, int):
raise TypeError("hue_offset数据类型应为整数")
if not 0 <= hue_offset <= 60:
raise ValueError("hue_offset应在060范围内")
# 初始化HSV颜色空间参数其中hue为色相saturation为饱和度value为亮度
hue, saturation, value = 0, 255, 128
while True:
# 初始化颜色列表
colors = []
for bead_idx in range(self.led_beads):
# 色相
hue = (hue + bead_idx * hue_offset) % 360
# 色域
region = hue // 60
# 色域内相对位置
remainder = (hue % 60) * 255 // 60
# RGB颜色通道中的最小值分量
primary = (value * (255 - saturation)) // 255
# RGB颜色通道中的过渡分量
tertiary = (value * remainder) // 255
# 根据色域将HSV转为RGB
if region == 0:
color = (value, tertiary, primary) # 由红色渐变为黄色
elif region == 1:
color = (value - tertiary, value, primary) # 由黄色渐变为绿色
elif region == 2:
color = (primary, value, tertiary) # 由绿色渐变为青色
elif region == 3:
color = (primary, value - tertiary, value) # 由青色渐变为蓝色
elif region == 4:
color = (tertiary, primary, value) # 由蓝色渐变为洋红色
else:
color = (value, primary, value - tertiary) # 由洋红色渐变为红色
colors.append(color)
self.set_colors(colors)
# 根据色域动态调整色相步长
hue = hue + [1, 3, 3, 3, 3, 1][region]
utime.sleep_ms(20)
"""
使用示例
RP2350ZERP 使用板载WS2812其占用引脚16
import utime
from utils.led import WS2812
rgb = WS2812()
while True:
rgb.iridesce()
utime.sleep_ms(20)
"""