# 导入必要的模块(机器操作、时间控制)
from machine import Pin, PWM, ADC # Pin引脚控制,PWM模拟信号,ADC数字信号转换
import utime # 时间控制模块
# ============== 蜂鸣器设置 ==============
# 创建4个主蜂鸣器(使用PWM引脚0-3),每个对应不同频率的音调
buzzers = [
PWM(Pin(0)), # 蜂鸣器1(连接到引脚0)
PWM(Pin(1)), # 蜂鸣器2
PWM(Pin(2)), # 蜂鸣器3
PWM(Pin(13)) # 蜂鸣器4
]
effect_buzzer1 = PWM(Pin(4)) # 特效蜂鸣器1
effect_buzzer2 = PWM(Pin(5)) # 特效蜂鸣器2
# ============== LED灯设置 ==============
# 创建3个LED灯(引脚16-18),每个灯代表不同距离范围
leds = [
Pin(16, Pin.OUT), # 近距离LED
Pin(17, Pin.OUT), # 中距离LED
Pin(18, Pin.OUT) # 远距离LED
]
# ============== 超声波测距模块 ==============
# 使用HC-SR04传感器测量距离
trigger = Pin(28, Pin.OUT) # 发送信号的引脚(像喇叭,发出超声波)
echo = Pin(27, Pin.IN) # 接收回波的引脚(像麦克风,接收返回的超声波)
# 测量距离的函数(单位:厘米)
def measure_distance():
# 1. 先确保停止发送信号
trigger.low()
utime.sleep_us(2)
# 2. 发送10微秒的高电平信号(发出超声波)
trigger.high()
utime.sleep_us(10)
trigger.low()
# 3. 记录发送超声波的时间点(信号发送时)
while echo.value() == 0: # 等待回波引脚变成高电平
signaloff = utime.ticks_us() # 记录开始时间
# 4. 记录接收超声波的时间点(信号返回时)
while echo.value() == 1: # 等待回波引脚变成低电平
signalon = utime.ticks_us() # 记录结束时间
# 5. 计算时间差并转换为距离(声速按340m/s计算)
timepassed = utime.ticks_diff(signalon, signaloff) # 计算时间差(微秒)
distance_cm = (timepassed * 0.0343) / 2 # 距离公式:距离 = (时间×声速)/2
return distance_cm # 返回测得的厘米距离
# ============== LED控制函数 ==============
# 点亮指定位置的LED灯(关闭其他灯)
def set_led(index):
for i in range(3): # 遍历3个LED
if i == index:
leds[i].value(1) # 点亮指定位置的LED
else:
leds[i].value(0) # 熄灭其他LED
# ============== 蜂鸣器演奏函数 ==============
# 让蜂鸣器播放指定频率和时长的音符
def play_note(buzzer, freq, duration_ms):
buzzer.freq(freq) # 设置音调频率(决定音高)
buzzer.duty_u16(30000) # 设置音量大小(30000中等音量)
utime.sleep_ms(duration_ms) # 持续指定的时间(毫秒)
buzzer.duty_u16(0) # 关闭蜂鸣器(停止发声)
# ============== 歌曲播放函数 ==============
# 播放音符序列(自动循环所有蜂鸣器)
def play_song(notes, durations):
# 遍历每个音符和对应的时值
for freq, dur in zip(notes, durations):
# 检查距离是否超过200cm(有人离开就停止播放)
distance = measure_distance()
if distance >= 200:
return # 停止播放歌曲
# 用4个蜂鸣器同时播放相同音符(产生和声效果)
for b in buzzers:
if freq > 0: # 正常音符(频率>0)
play_note(b, freq, int(dur * 150 / 200)) # 播放带速度控制的音符
else: # 休止符(频率=0)
b.duty_u16(0) # 关闭蜂鸣器
# 音符间隔(50毫秒停顿)
utime.sleep_ms(50)
# ============== 歌曲库 ==============
# 超级马里奥主题曲
def mario_theme():
notes = [659, 659, 659, 523, 659, 784, 392, 523,
392, 330, 440, 494, 466, 440, 392, 659,
784, 880, 698, 784, 659, 523, 587, 494]
durations = [150] * 24 # 所有音符都是150毫秒
play_song(notes, durations)
# 土耳其进行曲
def mehter_marsi():
notes = [392, 392, 392, 523, 392, 440, 494, 523,
440, 392, 392, 392, 523, 392, 440, 494,
523, 440, 392]
durations = [300, 300, 300, 600, 300, 300, 300, 600,
300, 300, 300, 600, 300, 300, 300, 600,
300, 300, 600]
play_song(notes, durations)
# ============== 主程序 ==============
# 循环检测距离并做出响应
while True:
distance = measure_distance() # 获取当前距离
# 近距离:0-100cm
if distance < 100:
set_led(0) # 点亮第一个LED(红色)
mehter_marsi() # 播放进行曲
# 中距离:100-200cm
elif distance >=100 and distance < 200:
set_led(1) # 点亮第二个LED(黄色)
mario_theme() # 播放马里奥主题曲
# 远距离:200cm以上
else:
set_led(2) # 点亮第三个LED(绿色)
for b in buzzers: # 关闭所有蜂鸣器
b.duty_u16(0)
utime.sleep(0.1) # 短暂延时