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
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 aboveGPIO.PWM(1, 4978)
isGPIO 1
output pulse is set to 4978Hz, i.e., one second has output period 4978pwm.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
Note definition frequency sound name notation
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
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()
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。