H_On个人小站

个人站

这都被你发现了【惊
奖励你一朵小红花~


Pi Pico MicroPython 控制无源蜂鸣器(赛博钢琴)

目录

接线

蜂鸣器的 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)