251121
This commit is contained in:
parent
cfec76ee40
commit
134384051f
|
|
@ -0,0 +1,14 @@
|
|||
import utime
|
||||
from machine import Pin
|
||||
from utils import MTS102
|
||||
|
||||
# 配置引脚
|
||||
led = Pin(0, Pin.OUT)
|
||||
toggle_switch = MTS102(1)
|
||||
|
||||
while True:
|
||||
if toggle_switch.switched:
|
||||
led.on()
|
||||
else:
|
||||
led.off()
|
||||
utime.sleep_ms(200)
|
||||
|
|
@ -0,0 +1,165 @@
|
|||
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), # 表示当前进度和速度
|
||||
}
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
import utime
|
||||
|
||||
|
||||
class WS2812B:
|
||||
"""RP2350的WS2812B驱动"""
|
||||
|
||||
def __init__(self, pin=16):
|
||||
"""
|
||||
初始化WS2812B驱动
|
||||
:param pin: WS2812B的DIN引脚编号(RP2350ZERO默认为16)
|
||||
"""
|
||||
|
||||
import rp2
|
||||
from machine import Pin
|
||||
|
||||
# 基于RP2350的可编程输入输出(PIO)生成输入数据信号
|
||||
@rp2.asm_pio(
|
||||
sideset_init=rp2.PIO.OUT_LOW, # 初始化侧置引脚为低电平
|
||||
out_shiftdir=rp2.PIO.SHIFT_LEFT, # 输出移位方向为左移(高位先出)
|
||||
autopull=True, # 自动从缓存区拉取数据
|
||||
pull_thresh=24, # 拉取数据阈值
|
||||
)
|
||||
def ws2812b():
|
||||
# 时序参数
|
||||
T1 = 3 # 比特0或比特1由低电平上升为高电平前的低电平周期数
|
||||
T2 = 2 # 比特0高电平周期数,或比特1前置高电平周期数
|
||||
T3 = 5 # 比特0由高电平下降为低电平后的低电平周期数,或比特1后置高电平周期数
|
||||
|
||||
wrap_target()
|
||||
label("bit_loop")
|
||||
# 从输出移位寄存器(OSR)移出一个比特到X寄存器,同时将侧置引脚置为低电平,延迟T1-1周期数
|
||||
out(x, 1).side(0)[T1 - 1]
|
||||
# 判断X寄存器中为比特0,同时将侧置引脚置为高电平,延迟T2-1周期数。若为比特0则跳转至bit_0,否则跳转至bit_loop,同时将侧置引脚置为高电平,延迟T3-1周期数
|
||||
jmp(not_x, "bit_0").side(1)[T2 - 1]
|
||||
jmp("bit_loop").side(1)[T3 - 1]
|
||||
label("bit_0")
|
||||
# 无操作,同时将侧置引脚置为低电平,延迟T3-1周期数
|
||||
nop().side(0)[T3 - 1]
|
||||
wrap()
|
||||
|
||||
try:
|
||||
# 初始化状态机
|
||||
self.state_mechine = rp2.StateMachine(
|
||||
0, ws2812b, freq=8_000_000, sideset_base=Pin(pin)
|
||||
)
|
||||
# 启动状态机
|
||||
self.state_mechine.active(1)
|
||||
|
||||
except Exception as exception:
|
||||
raise
|
||||
|
||||
def send(self, rgb):
|
||||
"""
|
||||
发送RGB颜色数据
|
||||
:param rgb: RGB颜色数据(元组)
|
||||
"""
|
||||
r, g, b = rgb
|
||||
# 组合RGB颜色数据
|
||||
rgb = (r << 24) | (g << 16) | (b << 8)
|
||||
|
||||
self.state_mechine.put(rgb)
|
||||
|
||||
def iridesce(self):
|
||||
"""炫彩"""
|
||||
# 色相
|
||||
H = 0
|
||||
# 饱和度
|
||||
S = 255
|
||||
# 亮度
|
||||
V = 16
|
||||
|
||||
while True:
|
||||
H = H % 360
|
||||
# 色域
|
||||
region = H // 60
|
||||
# 色域相对位置
|
||||
remainder = (H - region * 60) * 256 // 60
|
||||
|
||||
# 最小颜色分量值
|
||||
P = (V * (255 - S)) >> 8
|
||||
# 中间颜色分量值
|
||||
Q = (V * (255 - ((S * remainder) >> 8))) >> 8
|
||||
# 最大颜色分量值
|
||||
T = (V * (255 - ((S * (256 - remainder)) >> 8))) >> 8
|
||||
|
||||
state_mechine.send(
|
||||
{
|
||||
0: (V, T, P),
|
||||
1: (Q, V, P),
|
||||
2: (P, V, T),
|
||||
3: (P, Q, V),
|
||||
4: (T, P, V),
|
||||
}.get(region, (V, P, Q))
|
||||
)
|
||||
utime.sleep_ms(20)
|
||||
|
||||
H = H + 1
|
||||
134
发送摩斯码/main.py
134
发送摩斯码/main.py
|
|
@ -1,134 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from machine import Pin, PWM, Timer
|
||||
|
||||
import utime
|
||||
|
||||
|
||||
class MorseCodeTransmitter:
|
||||
"""摩斯码发送器"""
|
||||
|
||||
# 摩斯码本
|
||||
MORSECODEBOOK = {
|
||||
"A": ".-",
|
||||
"B": "-...",
|
||||
"C": "-.-.",
|
||||
"D": "-..",
|
||||
"E": ".",
|
||||
"F": "..-.",
|
||||
"G": "--.",
|
||||
"H": "....",
|
||||
"I": "..",
|
||||
"J": ".---",
|
||||
"K": "-.-",
|
||||
"L": ".-..",
|
||||
"M": "--",
|
||||
"N": "-.",
|
||||
"O": "---",
|
||||
"P": ".--.",
|
||||
"Q": "--.-",
|
||||
"R": ".-.",
|
||||
"S": "...",
|
||||
"T": "-",
|
||||
"U": "..-",
|
||||
"V": "...-",
|
||||
"W": ".--",
|
||||
"X": "-..-",
|
||||
"Y": "-.--",
|
||||
"Z": "--..",
|
||||
"0": "-----",
|
||||
"1": ".----",
|
||||
"2": "..---",
|
||||
"3": "...--",
|
||||
"4": "....-",
|
||||
"5": ".....",
|
||||
"6": "-....",
|
||||
"7": "--...",
|
||||
"8": "---..",
|
||||
"9": "----.",
|
||||
}
|
||||
|
||||
# 合法字符集
|
||||
CHARACTERSALLOWED = set("ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789")
|
||||
|
||||
def __init__(self):
|
||||
|
||||
# 单位时距(单位为毫秒)
|
||||
self.unit_time_interval = 120
|
||||
|
||||
# 初始化LED
|
||||
self.LED = Pin("LED", Pin.OUT, value=0)
|
||||
|
||||
def emit(self, characters: str) -> bool:
|
||||
"""发送摩斯码"""
|
||||
|
||||
"""
|
||||
:parma characters: 字符串,数据类型为字符
|
||||
|
||||
"""
|
||||
|
||||
# 检查字符串
|
||||
if not all(
|
||||
character.upper() in self.CHARACTERSALLOWED for character in characters
|
||||
):
|
||||
|
||||
print("allowed: a-z, 0-9, space")
|
||||
|
||||
return False
|
||||
|
||||
# 转为大写
|
||||
characters = characters.upper()
|
||||
|
||||
print(f"emitting {characters} ...", end="")
|
||||
|
||||
for character in characters:
|
||||
|
||||
# 单词间隔
|
||||
if character == " ":
|
||||
|
||||
utime.sleep_ms(self.unit_time_interval * 7)
|
||||
|
||||
continue
|
||||
|
||||
for code in self.MORSECODEBOOK.get(character):
|
||||
|
||||
# 点亮LED
|
||||
self.LED.value(1)
|
||||
|
||||
if code == ".":
|
||||
|
||||
utime.sleep_ms(self.unit_time_interval * 1)
|
||||
|
||||
else:
|
||||
|
||||
utime.sleep_ms(self.unit_time_interval * 3)
|
||||
|
||||
# 熄灭LED
|
||||
self.LED.value(0)
|
||||
|
||||
# 符号间隔
|
||||
utime.sleep_ms(self.unit_time_interval * 1)
|
||||
|
||||
# 字母间隔
|
||||
utime.sleep_ms(self.unit_time_interval * 3)
|
||||
|
||||
print("done")
|
||||
|
||||
return True
|
||||
|
||||
def __enter__(self):
|
||||
"""支持上下文管理"""
|
||||
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
"""退出"""
|
||||
|
||||
self.LED.off()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
with MorseCodeTransmitter() as transmitter:
|
||||
|
||||
result = transmitter.emit(characters="hello world")
|
||||
Loading…
Reference in New Issue