使用颜色传感器获取环境色彩数据,并显示在屏幕上。
用板载RGB LED实时显示当前感知到的颜色。
驱动蜂鸣器,根据颜色播放对应的八阶音符。
颜色传感器:TCS3200(可编程彩色光频转换器)。
输出设备:有源蜂鸣器(用于发声)、一个接近开关(用于触发)。
连接方式:由于开发板可用的Digital IO数量有限(仅7个),我使用杜邦线和面包板进行连接,并精心规划了引脚。


模式一:颜色读取与可视化
操作:按下对应按键。
逻辑:程序初始化传感器和RGB LED后,循环读取TCS3200输出的R、G、B三原色的频率值。将这些频率值映射到0-255的区间,然后直接驱动RGB LED发出相应颜色的光,实现“所见即所显”。
串口/屏幕打印:同时,将读取到的原始频率值或映射后的RGB值打印在串口监视器和开发板的TFT屏幕上,便于调试。
模式二:八阶音符播放
操作:按下另一个对应按键。
逻辑:程序内置一个对应“Do-Re-Mi-Fa-So-La-Si-Do”的固定频率数组。当触发时,蜂鸣器会以PWM方式依次播放这些频率的音符,每个音符持续一个可配置的时长后停止。

import time
import board
import digitalio
import neopixel
import pwmio
pwm = pwmio.PWMOut(board.D10,duty_cycle=0, frequency=440, variable_frequency=True)
note_names = ['C4', 'D4', 'E4', 'F4', 'G4', 'A4', 'B4', 'C5']
frequencies = [261, 293, 329, 349, 392, 440, 493, 523]
DEBOUNCE_TIME = 0.2
NOTE_DURATION = 0.5
def play_note(note_index):
if 0 <= note_index < len(note_names):
freq = frequencies[note_index]
pwm.frequency = int(freq)
pwm.duty_cycle = 2 ** 15
def stop_playing():
pwm.duty_cycle = 0
class TCS3200:
def __init__(self,s2_in,s3_in,out_pin_in):
self.s2 = digitalio.DigitalInOut(s2_in)
self.s3 = digitalio.DigitalInOut(s3_in)
self.out_pin = digitalio.DigitalInOut(out_pin_in)
self.s2.direction = digitalio.Direction.OUTPUT
self.s3.direction = digitalio.Direction.OUTPUT
self.out_pin.direction = digitalio.Direction.INPUT
def set_color_filter(self,color):
if color == 'R':
self.s2.value = False
self.s3.value = False
elif color == 'G':
self.s2.value = True
self.s3.value = True
elif color == 'B':
self.s2.value = False
self.s3.value = True
else:
self.s2.value = True
self.s3.value = False
def measure_frequency_one_channel(self,number_of_cycle=10):
timestamps = []
last_state = self.out_pin.value
while len(timestamps) < number_of_cycle:
current_state = self.out_pin.value
if current_state != last_state:
timestamps.append(time.monotonic_ns())
last_state = current_state
time.sleep(0.01)
periods = []
for i in range(4,len(timestamps),2):
periods_ns = timestamps[i] - timestamps[i-2]
periods.append(periods_ns)
avg_period_ns = sum(periods)/len(periods)
freq = 1_000_000_000 / avg_period_ns
return freq
color_senser = TCS3200(board.D13,board.D12,board.D11)
def get_color_freq(cs):
color_freq_array = []
cs.set_color_filter('R')
color_freq_array.append(cs.measure_frequency_one_channel())
cs.set_color_filter('G')
color_freq_array.append(cs.measure_frequency_one_channel())
cs.set_color_filter('B')
color_freq_array.append(cs.measure_frequency_one_channel())
return color_freq_array
def display_RGB_freq(color_freq_array):
print(f"Red freq = {color_freq_array[0]}")
print(f"Green freq = {color_freq_array[1]}")
print(f"Blue freq = {color_freq_array[2]}")
button = digitalio.DigitalInOut(board.D1)
button.switch_to_input(pull=digitalio.Pull.DOWN)
pixel = neopixel.NeoPixel(board.NEOPIXEL,1)
pixel.brightness = 0.1
pixel.fill((255,255,255)) # 初始化颜色
d2_button = digitalio.DigitalInOut(board.D2)
d2_button.switch_to_input(pull=digitalio.Pull.DOWN)
note_index = 0
note_start_time = time.monotonic()
previous_button_state = button.value
last_d2_state = d2_button.value
while True:
current_button_state = button.value
d2_current = d2_button.value
if previous_button_state and not current_button_state:
#task 1:print color
c_f_a = get_color_freq(color_senser)
display_RGB_freq(c_f_a)
c_f_a[0] = (c_f_a[0]/48) * 255
if c_f_a[0] > 255:
c_f_a[0] = 255
c_f_a[1] = (c_f_a[1]/44) * 255
if c_f_a[1] > 255:
c_f_a[1] = 255
c_f_a[2] = (c_f_a[2]/42) * 255
if c_f_a[2] > 255:
c_f_a[2] = 255
display_RGB_freq(c_f_a)
#task2: sample color and show in LED
pixel.fill((c_f_a[0],c_f_a[1],c_f_a[2]))
#task3: bibibi
if d2_current and not last_d2_state:
stop_playing()
play_note(note_index)
note_index = (note_index + 1) % len(note_names)
note_start_time = time.monotonic()
time.sleep(DEBOUNCE_TIME)
stop_playing()
last_d2_state = d2_current
previous_button_state = current_button_state # 更新状态
time.sleep(0.05) # 短暂延迟,减少CPU占用并帮助消抖
b站视频链接
我要赚赏金
