实现声音播放(蜂鸣器)
利用ESR32开发板和蜂鸣器,实现乐曲播放。原理是通过GPIO口控制PWM的输出,调节不同的音量大小来实现。
python
from machine import Pin, PWM
import time
gpio_04 = Pin(4)
beeper = PWM(gpio_04)
tone = [247, 262, 294, 330, 349, 392, 440, 494, 523, 587, 659, 698, 784, 1000] # 设置蜂鸣器的声音大小,由 ADC 值来控制,蜂鸣器声音范围 0-1023
for t in tone:
beeper.duty(512) # 设置PWM波的占空比为512,即50%
beeper.freq(t)
time.sleep(0.5) # 控制节拍速度
beeper.duty(0)
time.sleep(0.15)
beat = [2, 4, 6, 8, 10]
for j in beat:
beeper.duty(512) # 设置PWM波的占空比为512,即50%
beeper.freq(j * 100)
time.sleep(0.5) # 控制节拍速度
beeper.duty(0)
time.sleep(1)
for j in beat:
beeper.duty(512) # 设置PWM波的占空比为512,即50%
beeper.freq(1024)
time.sleep(0.12 * j) # 控制节拍速度
beeper.duty(0)
time.sleep(1)
案例
python
# 蜂鸣器演奏音乐的两个要素就是声音频率、声音持续时间,分别对应乐谱中的音调、节拍。
from machine import Pin, PWM
import time
gpio_04 = Pin(4)
beeper = PWM(gpio_04)
tone = [247, 262, 294, 330, 349, 392, 440, 494, 523, 587, 659, 698, 784, 1000] # 设置蜂鸣器的声音大小,由ADC值来控制,蜂鸣器声音范围0-1023
# 音调
music = [
5, 5, 6, 8, 7, 6, 5, 6, 13, 13,
5, 5, 6, 8, 7, 6, 5, 3, 13, 13,
2, 2, 3, 5, 3, 5, 6, 3, 2, 1,
6, 6, 5, 6, 5, 3, 6, 5, 13, 13,
5, 5, 6, 8, 7, 6, 5, 6, 13, 13,
5, 5, 6, 8, 7, 6, 5, 3, 13, 13,
2, 2, 3, 5, 3, 5, 6, 3, 2, 1,
6, 6, 5, 6, 5, 3, 6, 1,
13, 8, 9, 10, 10, 9, 8, 10, 9, 8, 6,
13, 6, 8, 9, 9, 8, 6, 9, 8, 6, 5,
13, 2, 3, 5, 5, 3, 5, 5, 6, 8, 7, 6,
6, 10, 9, 9, 8, 6, 5, 6, 8
]
# 节拍
beat = [
2, 4, 2, 2, 2, 2, 2, 8, 4, 4,
2, 4, 2, 2, 2, 2, 2, 8, 4, 4,
2, 4, 2, 4, 2, 2, 4, 2, 2, 8,
2, 4, 2, 2, 2, 2, 2, 8, 4, 4,
2, 4, 2, 2, 2, 2, 2, 8, 4, 4,
2, 4, 2, 2, 2, 2, 2, 8, 4, 4,
2, 4, 2, 4, 2, 2, 4, 2, 2, 8,
2, 4, 2, 2, 2, 2, 2, 8,
4, 2, 2, 2, 4, 2, 2, 2, 2, 2, 8,
4, 2, 2, 2, 4, 2, 2, 2, 2, 2, 8,
4, 2, 2, 2, 4, 2, 2, 5, 2, 6, 2, 4,
2, 2, 2, 4, 2, 4, 2, 2, 12
]
'''
# 方法一:
i = 0
while True:
speed = beat[i] # 设置播放速度,speed值越小,等待时间越短,播放速度越快
voice = tone[music[i]] # 音调大小
beeper.init(freq=voice) # PWM初始化并设置PWM频率
time.sleep(speed) # 等待时间
print(voice) # 打印出ADC值
i = i + 1 # i自增加1
if i > len(music) - 1: # 如果i的值大于music列表的长度
beeper.deinit() # 关闭PWM
break # 跳出循环
'''
# 方法二:
for i, j in zip(music, beat):
if (music == []): # 判断列表是否为空
beeper.duty(0) # 设置PWM波的占空比为0
else:
beeper.duty(512) # 设置PWM波的占空比为512,即50%
beeper.freq(tone[i - 1])
time.sleep(0.12 * j) # 控制节拍速度
beeper.duty(0)
time.sleep(0.15)
小案例-马里奥
python
from machine import Pin, PWM
import time
import _thread
beep = PWM(Pin(4), freq=50000, duty=500)
s2 = [50000, 262, 294, 330, 349, 392, 220, 247]
s3 = [50000, 523, 587, 659, 698, 784, 440, 494]
s4 = [50000, 1044, 1175, 1318, 1397, 1568, 880, 988]
def play(level, power=1, deltatime=200):
if power == 0:
beep.freq(s2[level])
elif power == 1:
beep.freq(s3[level])
elif power == 2:
beep.freq(s4[level])
time.sleep_ms(deltatime)
beep.freq(50000)
def plays(l):
for i in l:
if (len(i) == 3):
play(i[0], i[1], i[2])
else:
play(i[0], i[1])
def test():
plays([(3, 2), (3, 2), (0, 2), (3, 2), (0, 2), (1, 2), (3, 2), (0, 2), (5, 2), (0, 2, 500)])
plays([(1, 2, 600), (5, 1, 600), (3, 1, 600), (6, 1, 400), (7, 1, 400), (7, 1), (6, 1, 400)])
plays([(5, 1), (3, 2, 400), (5, 2), (6, 2, 400), (4, 2), (5, 2, 400), (3, 2, 400), (1, 2), (2, 2), (7, 1)])
plays([(1, 2, 600), (5, 1, 600), (3, 1, 600), (6, 1, 400), (7, 1, 400), (7, 1), (6, 1, 400)])
plays([(5, 1), (3, 2, 400), (5, 2), (6, 2, 400), (4, 2), (5, 2, 400), (3, 2, 400), (1, 2), (2, 2), (7, 1)])
_thread.start_new_thread(test, ())