MicroPython/RP2350ZERO/utils.py

166 lines
5.7 KiB
Python
Raw 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
class MTS102:
"""MTS102三脚二档钮子开关"""
def __init__(self, pin, pull_down=False):
"""
:param pin: 引脚编号
:param pull_down: 引脚下拉电阻断开为低电平接通为高电平默认为False。若使用下拉电阻因钮子接通后断开可能存留电荷/漏电故需在引脚和GND并联1K10K欧电阻
"""
if not isinstance(pull_down, bool):
raise TypeError("pull_down数据类型应为布尔")
self.pull_down = pull_down
# 尝试初始化引脚
try:
self.pin = Pin(
pin, Pin.IN, Pin.PULL_DOWN if self.pull_down else Pin.PULL_UP
)
except Exception as exception:
raise RuntimeError(f"初始化引脚发生异常,{str(exception)}") from exception
# 初始化上一次检测时间
self._last_time = utime.ticks_ms()
# 初始化上一次检测状态
self._last_state = self._get_state()
def _get_state(self):
"""获取状态0为断开1为接通"""
return self.pin.value() ^ (not self.pull_down)
def _debounce(self):
"""去抖"""
current_time = utime.ticks_ms()
current_state = self._get_state()
# 若当前与上一次检测间隔大于等于防抖时间则更新时间,又若状态不同则更新状态
if utime.ticks_diff(current_time, self._last_time) >= 20:
if current_state != self._last_state:
self._last_time = current_time
self._last_state = current_state
return self._last_state
@property
def switched(self):
"""是否接通"""
return self._debounce() == 1
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
from neopixel import NeoPixel
# 尝试初始化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 - region * 60) * 255 // 60
# 最小分量
P = (value * (255 - saturation)) // 255
# 过渡值
transition = (value * remainder) // 255
# 根据色域将HSV转为RGB并新增至颜色列表
colors.append(
{
0: (value, transition, P), # 由红色渐变为黄色
1: (value - transition, value, P), # 由黄色渐变为绿色
2: (P, value, transition), # 由绿色渐变为青色
3: (P, value - transition, value), # 由青色渐变为蓝色
4: (transition, P, value), # 由蓝色渐变为洋红色
5: (value, P, value - transition), # 由洋红色渐变为红色
}[region]
)
self.set_colors(colors)
# 根据色域动态调整色相步长
hue = hue + [1, 1, 1, 1, 1, 1][region]
utime.sleep_ms(100)
class Servo:
"""舵机(基类)"""
# 运动轨迹
_TRAJECTORIES = {
"linear": lambda x: (x, 1), # 表示当前进度和速度
}