Skip to content

实现声音播放(蜂鸣器)

利用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, ())