条件

  • 树莓派4B
  • 无源蜂鸣器3V: 3毛钱一个
  • 杜邦线: 2根
  • 语言: Python 3

接线

蜂鸣器正极: 作者应用的是GPIO 1 也就是第28个接口,
对于GPIO口没有要求,只有GPIO口都能够

GPIO 引脚图见: https://pinout.xyz/

蜂鸣器负极: 任意GND接口

无源蜂鸣器发出声音

想让无源蜂鸣器发出声音,其实就是继续输入PWM脉冲

import timeimport RPi.GPIO as GPIOGPIO.setmode(GPIO.BCM)GPIO.setwarnings(False)GPIO.setup(1, GPIO.OUT) # 设置GPIO 1为输入pwm = GPIO.PWM(1, 4978) # 设置GPIO 1为PWM输入, 脉冲为4978Hzpwm.start(0)pwm.ChangeDutyCycle(50) # 继续收回脉冲电平time.sleep(0.5) # 继续0.5s声音pwm.stop()GPIO.cleanup()
下面GPIO.PWM(1, 4978)就是GPIO 1的输入脉冲设置为4978Hz,即1秒有4978个输入周期
pwm.ChangeDutyCycle(50) 不能为100,因为100等于没有振荡电流,设置为50即可

音符对照表

援用: https://shumeipai.nxez.com/20...

其实上例中4978对应的音符是D8#,其它音符能够查看下图的


音符定义 频率 音名 简谱

开始编写歌曲

所以,只有晓得了简谱,比照上表,就能够调用不同的PWM脉冲来收回不同的声音。

如果你要实现和弦,那就须要多个蜂鸣器

铁血丹心的简谱

三个文件

txdx.py # 简谱tone.py # 音符表main.py

txdx.py

# 铁血丹心的简谱# 能够为2种格局# [音符名(string), 持续时间(s)]# [频率(int), 持续时间(s)]txdx_sheet = [    # 1    ['NOTE_A4', 1.5],  # 6    ['NOTE_G4', 0.5],  # 5    ['NOTE_A4', 1],  # 6    ['NOTE_G4', 0.5],  # 5    ['NOTE_E4', 0.5],  # 3    # 2    ['NOTE_G4', 1],  # 5    ['NOTE_D4', 3],  # 2    # 3    ['NOTE_C4', 1.5],  # 1    ['NOTE_A3', 0.5],  # .6    ['NOTE_D4', 0.5],  # 2    ['NOTE_E4', 0.5],  # 3    ['NOTE_G4', 0.5],  # 5    ['NOTE_F4', 0.5],  # 4    # 4    ['NOTE_E4', 3],  # 3    ['NOTE_E4', 0.5],  # 3    ['NOTE_G4', 0.5],  # 5    # 5    ['NOTE_A4', 1.5],  # 6    ['NOTE_G4', 0.5],  # 5    ['NOTE_A4', 1],  # 6    ['NOTE_G4', 0.5],  # 5    ['NOTE_E4', 0.5],  # 5    # 6    ['NOTE_G4', 1],  # 5    ['NOTE_D4', 3],  # 2    # 7    ['NOTE_C4', 1.5],  # 1    ['NOTE_A3', 0.5],  # .6    ['NOTE_D4', 0.5],  # 2    ['NOTE_E4', 0.5],  # 3    ['NOTE_G3', 0.5],  # .5    ['NOTE_B3', 0.5],  # .7    # 8    ['NOTE_A3', 4],  # .6    [0, 1],  # 0    ['NOTE_E4', 0.5],  # 3    ['NOTE_D4', 0.5],  # 2    ['NOTE_C4', 1.5],  # 1    ['NOTE_B3', 0.5],  # .7    #    ['NOTE_A3', 1.5],  # .6    ['NOTE_E3', 0.5],  # .3    ['NOTE_A3', 2],  # .6    # ['NOTE_A3', 1],        # .6    ['NOTE_A4', 0.5],  # 6    ['NOTE_G4', 0.5],  # 5    ['NOTE_E4', 1],  # 3    ['NOTE_G4', 0.5],  # 5    ['NOTE_D4', 0.5],  # 2    ['NOTE_E4', 3],  # 3    ['NOTE_E4', 0.5],  # 3    ['NOTE_D4', 0.5],  # 2    ['NOTE_C4', 1.5],  # 1    ['NOTE_B3', 0.5],  # .7    ['NOTE_A3', 1.5],  # .6    ['NOTE_E3', 0.5],  # .6    ['NOTE_A3', 2],  # .6    [0, 1],  # 0    ['NOTE_D4', 0.5],  # 2    ['NOTE_C4', 0.5],  # 1    ['NOTE_A3', 1],  # .6    ['NOTE_C4', 0.5],  # 1    ['NOTE_D4', 0.5],  # 1    ['NOTE_E4', 3],  # 3*/    ['NOTE_E4', 1],  # 3 逐草四方    ['NOTE_A4', 1.5],  # 6    ['NOTE_G4', 0.5],  # 5    ['NOTE_A4', 1],  # 6    ['NOTE_G4', 0.5],  # 5    ['NOTE_E4', 0.5],  # 3    ['NOTE_G4', 1],  # 5    ['NOTE_D4', 3],  # 2    ['NOTE_C4', 1.5],  # 1    ['NOTE_A3', 0.5],  # .6    ['NOTE_D4', 0.5],  # 2    ['NOTE_E4', 0.5],  # 3    ['NOTE_G4', 0.5],  # 5    ['NOTE_FS4', 0.5],  # #4    ['NOTE_E4', 3],  # 3    ['NOTE_E4', 0.5],  # 3    ['NOTE_G4', 0.5],  # 5    ['NOTE_A4', 1.5],  # 6    ['NOTE_G4', 0.5],  # 5    ['NOTE_A4', 1.0],  # 6    ['NOTE_G4', 0.5],  # 5    ['NOTE_E4', 0.5],  # 3    ['NOTE_G4', 1.0],  # 5    ['NOTE_D4', 3],  # 2    ['NOTE_C4', 1.5],  # 1    ['NOTE_A3', 0.5],  # .6    ['NOTE_D4', 0.5],  # 2    ['NOTE_E4', 0.5],  # 3    ['NOTE_G3', 0.5],  # .5    ['NOTE_B3', 0.5],  # .7    ['NOTE_A3', 3],  # .6    [0, 1],  # 0    ['NOTE_E4', 0.5],  # 3 应知爱意似    ['NOTE_D4', 0.5],  # 2    ['NOTE_C4', 1.0],  # 1    ['NOTE_C4', 0.5],  # 1    ['NOTE_B3', 0.5],  # .7    ['NOTE_A3', 1.5],  # .6    ['NOTE_E3', 0.5],  # .3    ['NOTE_A3', 2.0],  # .6    [0, 1],  # 0    ['NOTE_A3', 0.5],  # .6    ['NOTE_G3', 0.5],  # .5    ['NOTE_E3', 1.0],  # .3    ['NOTE_G3', 0.5],  # .5    ['NOTE_D3', 0.5],  # .2    ['NOTE_E3', 3.0],  # .3    [0, 1],  # 0    ['NOTE_E4', 0.5],  # 3 身经百劫也    ['NOTE_D4', 0.5],  # 2    ['NOTE_C4', 1.0],  # 1    ['NOTE_C4', 0.5],  # 1    ['NOTE_B3', 0.5],  # .7    ['NOTE_A3', 1.5],  # .6    ['NOTE_E4', 0.5],  # 3    ['NOTE_D4', 2.0],  # 2    [0, 1],  # 0    ['NOTE_D4', 0.5],  # 2    ['NOTE_C4', 0.5],  # 1    ['NOTE_A3', 1.0],  # .6    ['NOTE_B3', 0.5],  # .7    ['NOTE_G3', 0.5],  # .5    ['NOTE_A3', 3.0],  # .6]

tone.py 文件

TONE = {    'NOTE_B0' : 31,    'NOTE_C1' : 33,    'NOTE_CS1': 35,    'NOTE_D1' : 37,    'NOTE_DS1': 39,    'NOTE_E1' : 41,    'NOTE_F1' : 44,    'NOTE_FS1': 46,    'NOTE_G1' : 49,    'NOTE_GS1': 52,    'NOTE_A1' : 55,    'NOTE_AS1': 58,    'NOTE_B1' : 62,    'NOTE_C2' : 65,    'NOTE_CS2': 69,    'NOTE_D2' : 73,    'NOTE_DS2': 78,    'NOTE_E2' : 82,    'NOTE_F2' : 87,    'NOTE_FS2': 93,    'NOTE_G2' : 98,    'NOTE_GS2': 104,    'NOTE_A2' : 110,    'NOTE_AS2': 117,    'NOTE_B2' : 123,    'NOTE_C3' : 131,    'NOTE_CS3': 139,    'NOTE_D3' : 147,    'NOTE_DS3': 156,    'NOTE_E3' : 165,    'NOTE_F3' : 175,    'NOTE_FS3': 185,    'NOTE_G3' : 196,    'NOTE_GS3': 208,    'NOTE_A3' : 220,    'NOTE_AS3': 233,    'NOTE_B3' : 247,    'NOTE_C4' : 262,    'NOTE_CS4': 277,    'NOTE_D4' : 294,    'NOTE_DS4': 311,    'NOTE_E4' : 330,    'NOTE_F4' : 349,    'NOTE_FS4': 370,    'NOTE_G4' : 392,    'NOTE_GS4': 415,    'NOTE_A4' : 440,    'NOTE_AS4': 466,    'NOTE_B4' : 494,    'NOTE_C5' : 523,    'NOTE_CS5': 554,    'NOTE_D5' : 587,    'NOTE_DS5': 622,    'NOTE_E5' : 659,    'NOTE_F5' : 698,    'NOTE_FS5': 740,    'NOTE_G5' : 784,    'NOTE_GS5': 831,    'NOTE_A5' : 880,    'NOTE_AS5': 932,    'NOTE_B5' : 988,    'NOTE_C6' : 1047,    'NOTE_CS6': 1109,    'NOTE_D6' : 1175,    'NOTE_DS6': 1245,    'NOTE_E6' : 1319,    'NOTE_F6' : 1397,    'NOTE_FS6': 1480,    'NOTE_G6' : 1568,    'NOTE_GS6': 1661,    'NOTE_A6' : 1760,    'NOTE_AS6': 1865,    'NOTE_B6' : 1976,    'NOTE_C7' : 2093,    'NOTE_CS7': 2217,    'NOTE_D7' : 2349,    'NOTE_DS7': 2489,    'NOTE_E7' : 2637,    'NOTE_F7' : 2794,    'NOTE_FS7': 2960,    'NOTE_G7' : 3136,    'NOTE_GS7': 3322,    'NOTE_A7' : 3520,    'NOTE_AS7': 3729,    'NOTE_B7' : 3951,    'NOTE_C8' : 4186,    'NOTE_CS8': 4435,    'NOTE_D8' : 4699,    'NOTE_DS8': 4978,}

main.py

import timeimport RPi.GPIO as GPIOfrom tone import TONEGPIO.setmode(GPIO.BCM)GPIO.setwarnings(False)def beep(channel: int, freq: int, duration: float, *, rising_tone: float = 1):    """    播放一个音符    :param channel: GPIO的数字号,须要和下面的GPIO.setmode(GPIO.BCM)对应    :param freq: 频率    :param duration: 播放时长     :param rising_tone: 升降调 0.3 ~ 1.0 ~ 3.0    :return:     """    if freq <= 0:        time.sleep(duration)        return    pwm = GPIO.PWM(channel, freq * rising_tone) # 输入该频率的电平    try:        pwm.start(0)        pwm.ChangeDutyCycle(50)        if duration > 0:            time.sleep(duration) # 播放时长    finally:        pwm.stop()def play(channel: int, sheet: list):    """    播放简谱    简谱能够为如下格局(参照上文的txdx.py):    - [音符名(string), 持续时间(s)]    - [频率(int), 持续时间(s)]    :param channel: GPIO的数字号,须要和下面的GPIO.setmode(GPIO.BCM)对应    :param sheet: 简谱    :return:     """    GPIO.setup(channel, GPIO.OUT)    for m in sheet:        beep(channel, TONE[m[0]] if m[0] in TONE else int(m[0] or 0), m[1])try:    from txdx import txdx_sheet    play(1, txdx_sheet)finally:    GPIO.cleanup()