条件
- 树莓派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()