目录
接线
蜂鸣器的 I/O 引脚连接 21 脚。
实现赛博钢琴
使用 上一章 了解到的 PWM 引脚来输出音乐,只不过这次调节的不是 duty
(占空比),而是 freq
(频率)。
import machine
import utime
bee = machine.PWM(machine.Pin(21))
bee.duty_u16(0)
def play_one_key(tone=0, waitt=250):
if tone:
# 如果不演奏的话,关闭一个 waitt 的时间即可
# 因为频率 freq 不能设为 0,而占空比 duty 为 0 蜂鸣器则不会发声
bee.freq(tone)
bee.duty_u16(512)
utime.sleep_ms(waitt)
bee.duty_u16(0)
如果想看完整代码可以直接跳转 这里。
首先需要定义音阶的频率。他们都是一个个整数,网上可以搜到的,这里我定义了低一度,中音,和高一度的所有琴键。
D1_DO, D1_RE, D1_MI, D1_FA, D1_SOL, D1_LA, D1_XI = 262, 294, 330, 349, 392, 440, 494
D1_SDO, D1_SRE, D1_SFA, D1_SSOL, D1_SLA = 277, 311, 370, 415, 464
D1_DRE, D1_DMI, D1_DSOL, D1_DLA, D1_DXI = 277, 311, 370, 415, 464
DO, RE, MI, FA, SOL, LA, XI = 523, 587, 659, 698, 784, 880, 988
SDO, SRE, SFA, SSOL, SLA = 554, 622, 740, 831, 932
DRE, DMI, DSOL, DLA, DXI = 554, 622, 740, 831, 932
S1_DO, S1_RE, S1_MI, S1_FA, S1_SOL, S1_LA, S1_XI = 1046, 1175, 1318, 1397, 1568, 1760, 1976
S1_SDO, S1_SRE, S1_SFA, S1_SSOL, S1_SLA = 1109, 1245, 1480, 1661, 1865
S1_DRE, S1_DMI, S1_DSOL, S1_DLA, S1_DXI = 1109, 1245, 1480, 1661, 1865
为了方便我们创建一个类来实现钢琴功能:
class Piano(object):
# 在类中定义输出引脚
def __init__(self, pin):
self.bee = machine.PWM(machine.Pin(pin))
self.bee.duty_u16(0)
def play_one_key(self, tone=0, waitt=250):
if tone:
self.bee.freq(tone)
self.bee.duty_u16(512)
utime.sleep_ms(waitt)
self.bee.duty_u16(0)
# molody 为一个列表,储存需要演奏的音符
def play_song(self, melody, waitt=250):
for tone in melody:
self.play_one_key(tone, waitt)
最后定义我们要演奏的音乐,例如两只老虎:
melody = [
DO, DO, RE, RE, MI, MI, DO, DO,
DO, DO, RE, RE, MI, MI, DO, DO,
MI, MI, FA, FA, SOL, SOL, 0, 0,
MI, MI, FA, FA, SOL, SOL, 0, 0,
# 由于 ↓ 这里 ↓ 用到了 4 分音符,因此其他占 2 拍的音符我都写了两遍
SOL, LA, SOL, FA, MI, MI, DO, DO,
SOL, LA, SOL, FA, MI, MI, DO, DO,
RE, RE, D1_SOL, D1_SOL, DO, DO, 0, 0,
RE, RE, D1_SOL, D1_SOL, DO, DO, 0, 0,
]
代码
import machine
import utime
D1_DO, D1_RE, D1_MI, D1_FA, D1_SOL, D1_LA, D1_XI = 262, 294, 330, 349, 392, 440, 494
D1_SDO, D1_SRE, D1_SFA, D1_SSOL, D1_SLA = 277, 311, 370, 415, 464
D1_DRE, D1_DMI, D1_DSOL, D1_DLA, D1_DXI = 277, 311, 370, 415, 464
DO, RE, MI, FA, SOL, LA, XI = 523, 587, 659, 698, 784, 880, 988
SDO, SRE, SFA, SSOL, SLA = 554, 622, 740, 831, 932
DRE, DMI, DSOL, DLA, DXI = 554, 622, 740, 831, 932
S1_DO, S1_RE, S1_MI, S1_FA, S1_SOL, S1_LA, S1_XI = 1046, 1175, 1318, 1397, 1568, 1760, 1976
S1_SDO, S1_SRE, S1_SFA, S1_SSOL, S1_SLA = 1109, 1245, 1480, 1661, 1865
S1_DRE, S1_DMI, S1_DSOL, S1_DLA, S1_DXI = 1109, 1245, 1480, 1661, 1865
class Piano(object):
def __init__(self, pin):
self.bee = machine.PWM(machine.Pin(pin))
self.bee.duty_u16(0)
def play_one_key(self, tone=0, waitt=250):
if tone:
self.bee.freq(tone)
self.bee.duty_u16(512)
utime.sleep_ms(waitt)
self.bee.duty_u16(0)
def play_song(self, melody, waitt=250):
for tone in melody:
self.play_one_key(tone, waitt)
def two_tigers(piano):
melody = [
DO, DO, RE, RE, MI, MI, DO, DO,
DO, DO, RE, RE, MI, MI, DO, DO,
MI, MI, FA, FA, SOL, SOL, 0, 0,
MI, MI, FA, FA, SOL, SOL, 0, 0,
SOL, LA, SOL, FA, MI, MI, DO, DO,
SOL, LA, SOL, FA, MI, MI, DO, DO,
RE, RE, D1_SOL, D1_SOL, DO, DO, 0, 0,
RE, RE, D1_SOL, D1_SOL, DO, DO, 0, 0,
]
piano.play_song(melody, 150)
def leave(piano):
melody = [
SOL, SOL, MI, SOL, S1_DO, S1_DO, S1_DO, S1_DO,
LA, LA, S1_DO, LA, SOL, SOL, SOL, SOL,
SOL, SOL, DO, RE, MI, MI, RE, DO,
RE, RE, RE, RE, RE, RE, 0, 0,
SOL, SOL, MI, SOL, S1_DO, S1_DO, S1_DO, XI,
LA, LA, S1_DO, S1_DO, SOL, SOL, 0, 0,
SOL, SOL, RE, MI, FA, FA, FA, D1_XI,
DO, DO, DO, DO, DO, DO, 0, 0,
LA, LA, S1_DO, S1_DO, S1_DO, S1_DO, S1_DO, 0,
XI, XI, LA, XI, S1_DO, S1_DO, S1_DO, 0,
LA, XI, S1_DO, LA, LA, SOL, MI, DO,
RE, RE, RE, RE, RE, RE, 0, 0,
SOL, SOL, MI, SOL, S1_DO, S1_DO, S1_DO, XI,
LA, LA, S1_DO, S1_DO, SOL, SOL, 0, 0,
SOL, SOL, RE, MI, FA, FA, FA, D1_XI,
DO, DO, DO, DO, DO, DO, 0, 0,
]
piano.play_song(melody, 250)
p = Piano(21)
try:
while True:
# two_tigers(p)
leave(p)
except KeyboardInterrupt:
p.bee.duty_u16(0)