这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 【Let'sdo第3期-拾色播放器DIY】总结贴

共1条 1/1 1 跳转至

【Let'sdo第3期-拾色播放器DIY】总结贴

助工
2025-12-14 21:11:01     打赏

PS: 这帖子编辑器可真难用,还只有C++渲染

# 成果汇总
## 简介

1. 颜色传感器数据获取脚本2. 板载RGB全彩控制脚本3. 蜂鸣器八阶音符播放脚本
## 1. 颜色传感器数据获取
### 功能介绍
- 实现颜色传感器驱动,按键获取当前颜色数据并可以通过串口或屏幕进行打印;
### 代码实现

import board
import digitalio
import time
# 全局变量
NUM_CYCLES = 10  # 测试多少个周期
# 传感器引脚配置
s0 = digitalio.DigitalInOut(board.D12)
s1 = digitalio.DigitalInOut(board.D11)
s2 = digitalio.DigitalInOut(board.D10)
s3 = digitalio.DigitalInOut(board.D9)
out = digitalio.DigitalInOut(board.D6)
# 初始化板载按键D0/BOOT0,按下接地
button0 = digitalio.DigitalInOut(board.BUTTON)
button0.switch_to_input(pull=digitalio.Pull.UP)
# 初始化颜色传感器LED补光灯
led1 = digitalio.DigitalInOut(board.D5)
led1.direction = digitalio.Direction.OUTPUT
led1.value = False
# 白平衡校准系数 (初始值为1,需要实际校准)
r_scal = 1.0
g_scal = 1.0
b_scal = 1.0
# 初始化传感器引脚
def init_sensor():
    # 配置引脚方向
    s0.direction = digitalio.Direction.OUTPUT
    s1.direction = digitalio.Direction.OUTPUT
    s2.direction = digitalio.Direction.OUTPUT
    s3.direction = digitalio.Direction.OUTPUT
    out.direction = digitalio.Direction.INPUT
    
    # 设置频率缩放比为100% (最高精度)
    set_frequency_scaling(100)
    
    print("TCS3200传感器初始化完成")
# 设置传感器的频率缩放比例
def set_frequency_scaling(scaling):
    """
    设置传感器的频率缩放比例
    # s0  s1
    # L   L   关闭
    # L   H   2%
    # H   L   20%
    # H   H   100%
    """
    if scaling == 2:
        # 2%
        s0.value = False
        s1.value = True
    elif scaling == 20:
        # 20%
        s0.value = True
        s1.value = False
    elif scaling == 100:
        # 100%
        s0.value = True
        s1.value = True
    else:
        # 关闭
        s0.value = False
        s1.value = False
    
    time.sleep(0.01)  # 短暂延时稳定频率缩放比例
# 设置传感器的颜色滤波器
def set_color_filter(filter_type):
    """
    设置传感器的颜色滤波器
    # s2  s3
    # L   L   Red
    # H   H   Green
    # L   H   Blue
    # H   L   Clear(no filter)
    """
    if filter_type == "Red":
        s2.value = False
        s3.value = False
    elif filter_type == "Green":
        s2.value = True
        s3.value = True
    elif filter_type == "Blue":
        s2.value = False
        s3.value = True
    else:
        # "Clear"
        s2.value = True
        s3.value = False
    
    time.sleep(0.01)  # 短暂延时稳定滤波器
# 测量频率,并转换单位为Hz
def measure_frequency():
    timestamps = []
    last_state = out.value
    
    while len(timestamps) < NUM_CYCLES:
        current_state = out.value
        if current_state != last_state:
            # 发生边缘变化
            timestamps.append(time.monotonic_ns())
            last_state = current_state
    
    # 计数周期
    periods = []
    for i in range(2, len(timestamps), 2):
        period_ns = timestamps[i] - timestamps[i-2]  # 一个完整周期(两个边缘)
        periods.append(period_ns)
    
    avg_period_ns = sum(periods) / len(periods)
    frequency = 1000000000 / avg_period_ns  # 转换为 Hz
    
    return frequency
# 读取RGB三个通道的频率值
def read_rgb_freq():
    # 读取红色分量 (S2=0, S3=0)
    set_color_filter("Red")
    red_freq = measure_frequency()
    
    # 读取绿色分量 (S2=1, S3=1)
    set_color_filter("Green")
    green_freq = measure_frequency()
    
    # 读取蓝色分量 (S2=0, S3=1)
    set_color_filter("Blue")
    blue_freq = measure_frequency()
    
    return red_freq, green_freq, blue_freq
# 读取RGB颜色值
def read_rgb():
    # 读取RGB三个通道的频率值
    red_freq, green_freq, blue_freq = read_rgb_freq()
    
    # 应用白平衡校准 (18000/255 = 70)
    r = int(red_freq / 70 * r_scal)
    g = int(green_freq / 70 * g_scal)
    b = int(blue_freq / 70 * b_scal)
    
    # 限制在0-255范围
    r = max(0, min(255, r))
    g = max(0, min(255, g))
    b = max(0, min(255, b))
    
    return r, g, b
# 初始化传感器
init_sensor()
# 主循环
while True:
    # 读取按键0
    if not button0.value:
        print("按键按下,获取颜色数据...")
        led1.value = True  # 打开补光灯
        
        # 读取RGB颜色值
        r, g, b = read_rgb()
        print(f"颜色数据: R={r}, G={g}, B={b}")
        print(f"十六进制: #{r:02X}{g:02X}{b:02X}")
        
        led1.value = False  # 关闭补光灯
        time.sleep(0.5)  # 防抖处理
    
    time.sleep(0.05)  # 主循环延时

## 2. 板载RGB全彩控制
### 功能介绍
- 实现板载RGB的全彩控制,实时显示当前获取的颜色;
### 代码实现

import board
import digitalio
import time
import neopixel
# 全局变量
NUM_CYCLES = 10  # 测试多少个周期
# 传感器引脚配置
s0 = digitalio.DigitalInOut(board.D12)
s1 = digitalio.DigitalInOut(board.D11)
s2 = digitalio.DigitalInOut(board.D10)
s3 = digitalio.DigitalInOut(board.D9)
out = digitalio.DigitalInOut(board.D6)
# 初始化板载WS2812 RGB LED(使用neopixel库)
# Adafruit ESP32-S3 Reverse TFT Feather板载一颗WS2812 LED
pixel_pin = board.NEOPIXEL  # 板载WS2812 LED的引脚
num_pixels = 1  # 只有一颗LED
# 使用neopixel库初始化LED
pixels = neopixel.NeoPixel(pixel_pin, num_pixels, brightness=0.3, auto_write=False)
# 初始化颜色传感器LED补光灯
led1 = digitalio.DigitalInOut(board.D5)
led1.direction = digitalio.Direction.OUTPUT
led1.value = False
# 白平衡校准系数 (初始值为1,需要实际校准)
r_scal = 1.0
g_scal = 1.0
b_scal = 1.0
# 初始化传感器引脚
def init_sensor():
    # 配置引脚方向
    s0.direction = digitalio.Direction.OUTPUT
    s1.direction = digitalio.Direction.OUTPUT
    s2.direction = digitalio.Direction.OUTPUT
    s3.direction = digitalio.Direction.OUTPUT
    out.direction = digitalio.Direction.INPUT
    
    # 设置频率缩放比为100% (最高精度)
    set_frequency_scaling(100)
    
    print("TCS3200传感器初始化完成")
# 设置传感器的频率缩放比例
def set_frequency_scaling(scaling):
    if scaling == 2:
        # 2%
        s0.value = False
        s1.value = True
    elif scaling == 20:
        # 20%
        s0.value = True
        s1.value = False
    elif scaling == 100:
        # 100%
        s0.value = True
        s1.value = True
    else:
        # 关闭
        s0.value = False
        s1.value = False
    
    time.sleep(0.01)  # 短暂延时稳定频率缩放比例
# 设置传感器的颜色滤波器
def set_color_filter(filter_type):
    if filter_type == "Red":
        s2.value = False
        s3.value = False
    elif filter_type == "Green":
        s2.value = True
        s3.value = True
    elif filter_type == "Blue":
        s2.value = False
        s3.value = True
    else:
        # "Clear"
        s2.value = True
        s3.value = False
    
    time.sleep(0.01)  # 短暂延时稳定滤波器
# 测量频率,并转换单位为Hz
def measure_frequency():
    timestamps = []
    last_state = out.value
    
    while len(timestamps) < NUM_CYCLES:
        current_state = out.value
        if current_state != last_state:
            # 发生边缘变化
            timestamps.append(time.monotonic_ns())
            last_state = current_state
    
    # 计数周期
    periods = []
    for i in range(2, len(timestamps), 2):
        period_ns = timestamps[i] - timestamps[i-2]  # 一个完整周期(两个边缘)
        periods.append(period_ns)
    
    avg_period_ns = sum(periods) / len(periods)
    frequency = 1000000000 / avg_period_ns  # 转换为 Hz
    
    return frequency
# 读取RGB三个通道的频率值
def read_rgb_freq():
    # 读取红色分量 (S2=0, S3=0)
    set_color_filter("Red")
    red_freq = measure_frequency()
    
    # 读取绿色分量 (S2=1, S3=1)
    set_color_filter("Green")
    green_freq = measure_frequency()
    
    # 读取蓝色分量 (S2=0, S3=1)
    set_color_filter("Blue")
    blue_freq = measure_frequency()
    
    return red_freq, green_freq, blue_freq
# 读取RGB颜色值
def read_rgb():
    # 读取RGB三个通道的频率值
    red_freq, green_freq, blue_freq = read_rgb_freq()
    
    # 应用白平衡校准 (18000/255 = 70)
    r = int(red_freq / 70 * r_scal)
    g = int(green_freq / 70 * g_scal)
    b = int(blue_freq / 70 * b_scal)
    
    # 限制在0-255范围
    r = max(0, min(255, r))
    g = max(0, min(255, g))
    b = max(0, min(255, b))
    
    return r, g, b
# 设置WS2812 RGB LED颜色
def set_rgb_color(r, g, b):
    # WS2812直接使用RGB值(0-255)
    pixels[0] = (r, g, b)
    pixels.show()  # 更新LED显示
# 初始化传感器
init_sensor()
# 主循环
while True:
    led1.value = True  # 打开补光灯
    
    # 读取RGB颜色值
    r, g, b = read_rgb()
    print(f"实时颜色数据: R={r}, G={g}, B={b}")
    
    # 设置RGB LED颜色
    set_rgb_color(r, g, b)
    
    led1.value = False  # 关闭补光灯
    time.sleep(0.5)  # 延时
## 3. 蜂鸣器八阶音符播放
### 功能介绍
- 实现蜂鸣器驱动,并播放八阶音符;
### 代码实现
import board
import pwmio
import time
import digitalio
# 初始化PWMOut,接蜂鸣器控制脚(D4)
pwm0 = pwmio.PWMOut(board.D4,
    duty_cycle=0,
    frequency=1000,
    variable_frequency=True
)
# 初始化板载按键D0/BOOT0,按下接地
button0 = digitalio.DigitalInOut(board.BUTTON)
button0.switch_to_input(pull=digitalio.Pull.UP)
# 8音阶频率(C4, D4, E4, F4, G4, A4, B4, C5)
note_names = [
    'C4',
    'D4',
    'E4',
    'F4',
    'G4',
    'A4',
    'B4',
    'C5'
]
frequencies = [
    261,
    293,
    329,
    349,
    392,
    440,
    493,
    523
]
# 音符播放控制函数
def play_note(note_index):
    if 0 <= note_index < len(note_names):
        name = note_names[note_index]
        freq = frequencies[note_index]
        print(f"播放音符: {name} at {freq} Hz")
        pwm0.frequency = int(freq)
        pwm0.duty_cycle = 2 ** 15  # 50%占空比
    else:
        print(f"无效的音符索引: {note_index}")
# 停止播放音符
def stop_playing():
    pwm0.duty_cycle = 0
    print("停止播放")
# 播放所有八阶音符
def play_all_notes():
    for i in range(len(note_names)):
        play_note(i)
        time.sleep(0.5)  # 每个音符播放0.5秒
        stop_playing()
        time.sleep(0.1)  # 音符间间隔0.1秒
print("蜂鸣器驱动初始化完成")
print("按下按键开始播放八阶音符")
# 主循环
while True:
    # 读取按键0
    if not button0.value:
        print("\n开始播放八阶音符...")
        play_all_notes()
        print("八阶音符播放完成")
        time.sleep(0.5)  # 防抖处理
    
    time.sleep(0.05)  # 主循环延时

## 总结
三个脚本均已实现所需功能,基础任务全部完成,结构清晰,易于理解和修改。每个脚本都包含了必要的注释,方便抄作业~。
基础任务:
1、实现颜色传感器驱动,按键获取当前颜色数据并可以通过串口或屏幕进行打印;2、实现板载RGB的全彩控制,实时显示当前获取的颜色;3、实现蜂鸣器驱动,并播放八阶音符;

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]