1
Source code: https://github.com/fly-studio/gpio-examples/tree/master/buzzer

condition

  • Raspberry Pi 4B
  • Passive buzzer 3V: 3 cents each
  • Dupont line: 2
  • Language: Python 3

wiring

image.png

buzzer positive: author uses GPIO 1, which is the 28th interface,
There is no requirement for the GPIO port, as long as the GPIO port can be used

GPIO pin diagram see: https://pinout.xyz/

buzzer negative electrode: any GND interface

Passive buzzer makes a sound

Want to make a passive buzzer sound, in fact, it is continuously outputting PWM pulses

import time
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)

GPIO.setup(1, GPIO.OUT) # 设置GPIO 1为输出
pwm = GPIO.PWM(1, 4978) # 设置GPIO 1为PWM输出, 脉冲为4978Hz
pwm.start(0)
pwm.ChangeDutyCycle(50) # 持续发出脉冲电平
time.sleep(0.5) # 持续0.5s声音
pwm.stop()

GPIO.cleanup()
The above GPIO.PWM(1, 4978) is GPIO 1 output pulse is set to 4978Hz, i.e., one second has output period 4978
pwm.ChangeDutyCycle(50) cannot be 100, because 100 is equal to no oscillating current, just set it to 50

Note comparison table

Reference: https://shumeipai.nxez.com/2020/11/18/raspberry-pi-controls-the-buzzer-to-play-music.html

In fact, the note corresponding to 4978 in the above example is D8# , other notes can be viewed in the figure below

image.png
Note definition frequency sound name notation
image.png

Start writing a song

Therefore, as long as you know the numbered musical notation and compare with the above table, you can call different PWM pulses to make different sounds.

If you want to achieve chords, you need multiple buzzers

Notation of Jagged Heart

image.png

Three files

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 file

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 time
import RPi.GPIO as GPIO
from tone import TONE

GPIO.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()

member
6.2k 声望158 粉丝

擅长计算机开关机、Windows系统的安装。