import utime from machine import Pin class MTS102: """MTS102(三脚二档钮子开关)""" def __init__(self, pin, pull_down=False): """ :param pin: 引脚编号 :param pull_down: 引脚下拉电阻(断开为低电平,接通为高电平),默认为False。若使用下拉电阻,因钮子接通后断开可能存留电荷/漏电故需在引脚和GND并联1K~10K欧电阻 """ 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("通道数据数值应在0~255范围内") 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数值应在0~60范围内") # 初始化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), # 表示当前进度和速度 }