【得捷电子Follow me第3期】任务3:控制蜂鸣器播放音乐
[复制链接]
本帖最后由 xinmeng_wit 于 2023-11-29 21:26 编辑
一、任务主要内容
二、蜂鸣器引脚配置
XIAO扩展板上集成了一颗蜂鸣器,根据seeed官方的资料显示,蜂鸣器接在扩展板上的A3引脚,在对应到ESP32C3的引脚是GPIO5
于是,就可以根据引脚信息来对引脚进行配置。
由于我们需要使用蜂鸣器发出不同频率的声音,所以这里就使用pwm功能来进行调整变频率。
GPIO5引脚初始化:
from machine import PWM,Pin
# Buzzer settings
buzzer = PWM(Pin(5),freq=1024,duty=512)
初始频率指定为1024Hz,占空比参数为512,即50% (范围0~1023),初始freq和duty可以随意指定,因为后面会根据音符来动态调整。
这样初始化完成后,蜂鸣器就能发出声音了,但是这个声音是固定不变的。
三、蜂鸣器播放音乐
要想让蜂鸣器根据乐谱来播放音乐,就必须将乐谱量化成代码可以识别的数字,那么对于乐谱来说,基本上量化出来的参数就是两个,一个是频率,一个是时长。
每一个音符(1,2,3,4,5,6,7)对应了一种频率,这些频率都是知道的,可以在网络上查找相关的资料。
补充一点的是,每个音符又分为高音,中音和低音,分别对应不同的频率,也就是每个音符可以对应三种频率,具体要根据音乐简谱来定
对于时长,就需要根据实际的音乐简谱来对应了,每一个歌曲都是不一样的。
下面就是歌曲《沧海一声笑》的简朴,根据这个简朴就可以知道每个音符的频率和时长
量化的频率和时长:
X0 = -1 # 休止符
D5 = 262 # 低音(5)
D6 = 294 # 低音(6)
Z1 = 349 # 中音(1)
Z2 = 392 # 中音(2)
Z3 = 440 # 中音(3)
Z5 = 523 # 中音(5)
Z6 = 587 # 中音(6)
# 频率
tune = [ Z6,Z5,Z3,Z2,Z1, Z3,Z2,Z1,D6,D5,X0, D5,D6,D5,D6,Z1,Z2,Z3,Z5, Z6,Z5,Z3,Z2,Z1,Z2,
Z6,Z6,Z5,Z3,Z2,Z1, Z3,Z2,Z1,D6,D5,X0, D5,D6,D5,D6,Z1,Z2,Z3,Z5, Z6,Z5,Z3,Z2,Z1,Z2,
Z6,Z6,Z5,Z3,Z2,Z1, Z3,Z2,Z1,D6,D5,X0, D5,D6,D5,D6,Z1,Z2,Z3,Z5, Z6,Z5,Z3,Z2,Z1,Z2,
Z6,Z6,Z5,Z3,Z2,Z1, Z3,Z2,Z1,D6,D5,X0, D5,D6,D5,D6,Z1,Z2,Z3,Z5, Z6,Z5,Z3,Z2,Z1
]
# 时长
duration = [ 0.75,0.25,0.5,0.5,2, 0.75,0.25,0.5,0.5,1.8,0.2, 0.75,0.25,0.75,0.25,0.75,0.25,0.5,0.5, 0.75,0.25,0.5,0.25,0.25,2,
0.75,0.25,0.25,0.5,0.5,2, 0.75,0.25,0.5,0.5,1.8,0.2, 0.75,0.25,0.75,0.25,0.75,0.25,0.5,0.5, 0.75,0.25,0.5,0.25,0.25,2,
0.75,0.25,0.25,0.5,0.5,2, 0.75,0.25,0.5,0.5,1.8,0.2, 0.75,0.25,0.75,0.25,0.75,0.25,0.5,0.5, 0.75,0.25,0.5,0.25,0.25,2,
0.75,0.25,0.25,0.5,0.5,2, 0.75,0.25,0.5,0.5,1.8,0.2, 0.75,0.25,0.75,0.25,0.75,0.25,0.5,0.5, 0.75,0.25,0.5,0.5,2
]
根据这两张表去设置pwm的频率和时长就能让蜂鸣器播放出歌曲《沧海一声笑》了。
如下就是根据这两张表动态设置pwm参数的程序,来源于seeed官方例程,稍作修改:
def buzzer_play():
total_notes = len(tune)
for i in range(total_notes):
current_note = tune[i]
wait = duration[i]
if current_note != -1:
buzzer.duty(512) # Set duty cycle for sound
buzzer.freq(current_note) # Set frequency of the note
else:
buzzer.duty(0) # Turn off the sound
time.sleep_ms(int(wait * 800))
buzzer.duty(0) # Turn off the sound
另外,代码里面time.sleep_ms(int(wait * 800))是用来控制播放速度的,可以根据实际情况做调整。
其实,更确切地说,这个地方实际上是控制音乐每一拍的时长。
四、视频演示
buzzer
|