1.首先从machine库导入Pin和PWM,从utime库导入sleep.

from machine import Pin, PWM
from utime import sleep

2.初始化PWM(也就是脉宽调制)到管脚PIO(22),并分配它为变量buzzer。

buzzer = PWM(Pin(22))

3.给变量buzzer分配一个频率属性,选择10到12,000之间的数值,数值越大音调越高,我们可以设定为500.

buzzer.freq(500)

4.将蜂鸣器对象的duty_u16属性设置为1000,这就能让蜂鸣器尽可能地响。更低的值更安静,0根本没有声音。

buzzer.duty_u16(1000)

5.设置1秒的延迟,然后将duty设置为0,这样声音就会停止。如果不这样做,即使程序执行完毕,嗡嗡声也会继续。

sleep(1)
buzzer.duty_u16(0)

最终的代码:

from machine import Pin, PWM
from utime import sleep
 
buzzer = PWM(Pin(22))
buzzer.freq(500)
buzzer.duty_u16(1000)
sleep(1)
buzzer.duty_u16(0)

因为你可以使用不同的频率,你可以创造一个完整的音符阵列。网上有一些音符频率的列表,其中许多可以追溯到Brett Hagman在Github上的Arduino音调库。我们将使用这些值创建一个列表,以便在代码早期播放任何歌曲。

1.在管脚PIO(22)上导入必要的库并初始化PWM。

from machine import Pin, PWM
from utime import sleep
 
buzzer = PWM(Pin(22))

2.使用下列值创建一个名为tones的字典。

tones = {
"B0": 31,
"C1": 33,
"CS1": 35,
"D1": 37,
"DS1": 39,
"E1": 41,
"F1": 44,
"FS1": 46,
"G1": 49,
"GS1": 52,
"A1": 55,
"AS1": 58,
"B1": 62,
"C2": 65,
"CS2": 69,
"D2": 73,
"DS2": 78,
"E2": 82,
"F2": 87,
"FS2": 93,
"G2": 98,
"GS2": 104,
"A2": 110,
"AS2": 117,
"B2": 123,
"C3": 131,
"CS3": 139,
"D3": 147,
"DS3": 156,
"E3": 165,
"F3": 175,
"FS3": 185,
"G3": 196,
"GS3": 208,
"A3": 220,
"AS3": 233,
"B3": 247,
"C4": 262,
"CS4": 277,
"D4": 294,
"DS4": 311,
"E4": 330,
"F4": 349,
"FS4": 370,
"G4": 392,
"GS4": 415,
"A4": 440,
"AS4": 466,
"B4": 494,
"C5": 523,
"CS5": 554,
"D5": 587,
"DS5": 622,
"E5": 659,
"F5": 698,
"FS5": 740,
"G5": 784,
"GS5": 831,
"A5": 880,
"AS5": 932,
"B5": 988,
"C6": 1047,
"CS6": 1109,
"D6": 1175,
"DS6": 1245,
"E6": 1319,
"F6": 1397,
"FS6": 1480,
"G6": 1568,
"GS6": 1661,
"A6": 1760,
"AS6": 1865,
"B6": 1976,
"C7": 2093,
"CS7": 2217,
"D7": 2349,
"DS7": 2489,
"E7": 2637,
"F7": 2794,
"FS7": 2960,
"G7": 3136,
"GS7": 3322,
"A7": 3520,
"AS7": 3729,
"B7": 3951,
"C8": 4186,
"CS8": 4435,
"D8": 4699,
"DS8": 4978
}

3.为你的歌曲创建一个音符列表(又名数组)。用字母P表示音乐中的停顿。每个音符都应该用引号括起来。

song = ["E5","G5","A5","P","E5","G5","B5","A5","P","E5","G5","A5","P","G5","E5"]

向在这个帖子上分享这段著名riff音符的人们致敬。

4.创建一个名为playtone的函数,可以使用任意频率并以最大音量播放。

def playtone(frequency):
    buzzer.duty_u16(1000)
    buzzer.freq(frequency)

5.创建一个名为bequiet的函数,通过将duty_u16更改为0来使蜂鸣器静音。

def bequiet():
    buzzer.duty_u16(0)

6.创建一个名为playsong的函数,您将使用它来遍历音符数组并播放每一个音符,或者在看到P时暂停。

def playsong(mysong):
    for i in range(len(mysong)):
        if (mysong[i] == "P"):
            bequiet()
        else:
            playtone(tones[mysong[i]])
        sleep(0.3)
    bequiet()

是这样的。首先,我们创建一个for循环来遍历myssong数组中的所有值。如果值等于P,则触发be quiet;如果值不等于P,则触发playtone。注意,playtone需要一个数字频率值,因此我们必须从音调列表中获取每个音符的数字。如果我们只是播放tone(myssong [i]),它将失败,因为它将尝试播放字符串“E5”,而不是频率659,这是它需要的整数。

对于每个音调或暂停,系统维持0.3秒的睡眠状态。如果你想要更快的节奏,你可以降低时间。如果你想要慢节奏,那就加快节奏。

7.使用song参数触发playsong函数。

playsong(song)

运行此代码时,您将听到蜂鸣器播放熟悉的旋律。完整的代码应该是这样的:

from machine import Pin, PWM
from utime import sleep
buzzer = PWM(Pin(15))
 
tones = {
"B0": 31,
"C1": 33,
"CS1": 35,
"D1": 37,
"DS1": 39,
"E1": 41,
"F1": 44,
"FS1": 46,
"G1": 49,
"GS1": 52,
"A1": 55,
"AS1": 58,
"B1": 62,
"C2": 65,
"CS2": 69,
"D2": 73,
"DS2": 78,
"E2": 82,
"F2": 87,
"FS2": 93,
"G2": 98,
"GS2": 104,
"A2": 110,
"AS2": 117,
"B2": 123,
"C3": 131,
"CS3": 139,
"D3": 147,
"DS3": 156,
"E3": 165,
"F3": 175,
"FS3": 185,
"G3": 196,
"GS3": 208,
"A3": 220,
"AS3": 233,
"B3": 247,
"C4": 262,
"CS4": 277,
"D4": 294,
"DS4": 311,
"E4": 330,
"F4": 349,
"FS4": 370,
"G4": 392,
"GS4": 415,
"A4": 440,
"AS4": 466,
"B4": 494,
"C5": 523,
"CS5": 554,
"D5": 587,
"DS5": 622,
"E5": 659,
"F5": 698,
"FS5": 740,
"G5": 784,
"GS5": 831,
"A5": 880,
"AS5": 932,
"B5": 988,
"C6": 1047,
"CS6": 1109,
"D6": 1175,
"DS6": 1245,
"E6": 1319,
"F6": 1397,
"FS6": 1480,
"G6": 1568,
"GS6": 1661,
"A6": 1760,
"AS6": 1865,
"B6": 1976,
"C7": 2093,
"CS7": 2217,
"D7": 2349,
"DS7": 2489,
"E7": 2637,
"F7": 2794,
"FS7": 2960,
"G7": 3136,
"GS7": 3322,
"A7": 3520,
"AS7": 3729,
"B7": 3951,
"C8": 4186,
"CS8": 4435,
"D8": 4699,
"DS8": 4978
}
 
song = ["E5","G5","A5","P","E5","G5","B5","A5","P","E5","G5","A5","P","G5","E5"]
 
def playtone(frequency):
    buzzer.duty_u16(1000)
    buzzer.freq(frequency)
 
def bequiet():
    buzzer.duty_u16(0)
 
def playsong(mysong):
    for i in range(len(mysong)):
        if (mysong[i] == "P"):
            bequiet()
        else:
            playtone(tones[mysong[i]])
        sleep(0.3)
    bequiet()
playsong(song)

onlinesequencer

James的Buzz_music代码

from machine import Pin, PWM
from math import ceil
 
tones = {
    'C0':16,
    'C#0':17,
    'D0':18,
    'D#0':19,
    'E0':21,
    'F0':22,
    'F#0':23,
    'G0':24,
    'G#0':26,
    'A0':28,
    'A#0':29,
    'B0':31,
    'C1':33,
    'C#1':35,
    'D1':37,
    'D#1':39,
    'E1':41,
    'F1':44,
    'F#1':46,
    'G1':49,
    'G#1':52,
    'A1':55,
    'A#1':58,
    'B1':62,
    'C2':65,
    'C#2':69,
    'D2':73,
    'D#2':78,
    'E2':82,
    'F2':87,
    'F#2':92,
    'G2':98,
    'G#2':104,
    'A2':110,
    'A#2':117,
    'B2':123,
    'C3':131,
    'C#3':139,
    'D3':147,
    'D#3':156,
    'E3':165,
    'F3':175,
    'F#3':185,
    'G3':196,
    'G#3':208,
    'A3':220,
    'A#3':233,
    'B3':247,
    'C4':262,
    'C#4':277,
    'D4':294,
    'D#4':311,
    'E4':330,
    'F4':349,
    'F#4':370,
    'G4':392,
    'G#4':415,
    'A4':440,
    'A#4':466,
    'B4':494,
    'C5':523,
    'C#5':554,
    'D5':587,
    'D#5':622,
    'E5':659,
    'F5':698,
    'F#5':740,
    'G5':784,
    'G#5':831,
    'A5':880,
    'A#5':932,
    'B5':988,
    'C6':1047,
    'C#6':1109,
    'D6':1175,
    'D#6':1245,
    'E6':1319,
    'F6':1397,
    'F#6':1480,
    'G6':1568,
    'G#6':1661,
    'A6':1760,
    'A#6':1865,
    'B6':1976,
    'C7':2093,
    'C#7':2217,
    'D7':2349,
    'D#7':2489,
    'E7':2637,
    'F7':2794,
    'F#7':2960,
    'G7':3136,
    'G#7':3322,
    'A7':3520,
    'A#7':3729,
    'B7':3951,
    'C8':4186,
    'C#8':4435,
    'D8':4699,
    'D#8':4978,
    'E8':5274,
    'F8':5588,
    'F#8':5920,
    'G8':6272,
    'G#8':6645,
    'A8':7040,
    'A#8':7459,
    'B8':7902,
    'C9':8372,
    'C#9':8870,
    'D9':9397,
    'D#9':9956,
    'E9':10548,
    'F9':11175,
    'F#9':11840,
    'G9':12544,
    'G#9':13290,
    'A9':14080,
    'A#9':14917,
    'B9':15804
}
 
#Time, Note, Duration, Instrument (onlinesequencer.net schematic format)
#0 D4 8 0;0 D5 8 0;0 G4 8 0;8 C5 2 0;10 B4 2 0;12 G4 2 0;14 F4 1 0;15 G4 17 0;16 D4 8 0;24 C4 8 0
 
class music:
    def __init__(self, songString='0 D4 8 0', looping=True, tempo=3, duty=2512, pin=None, pins=[Pin(0)]):
        self.tempo = tempo
        self.song = songString
        self.looping = looping
        self.duty = duty
 
        self.stopped = False
 
        self.timer = -1
        self.beat = -1
        self.arpnote = 0
 
        self.pwms = []
 
        if (not (pin is None)):
            pins = [pin]
 
        i = 0
        for pin in pins:
            self.pwms.append(PWM(pins[i]))
            i = i + 1
 
        self.notes = []
 
        self.playingNotes = []
        self.playingDurations = []
 
 
        #Find the end of the song
        self.end = 0
        splitSong = self.song.split(";")
        for note in splitSong:
            snote = note.split(" ")
            testEnd = round(float(snote[0])) + ceil(float(snote[2]))
            if (testEnd > self.end):
                self.end = testEnd
 
        #Create empty song structure
        while (self.end > len(self.notes)):
            self.notes.append(None)
 
        #Populate song structure with the notes
        for note in splitSong:
            snote = note.split(" ")
            beat = round(float(snote[0]));
 
            if (self.notes[beat] == None):
                self.notes[beat] = []
            self.notes[beat].append([snote[1],ceil(float(snote[2]))]) #Note, Duration
 
 
        #Round up end of song to nearest bar
        self.end = ceil(self.end / 8) * 8
 
    def stop(self):
        for pwm in self.pwms:
            pwm.deinit()
        self.stopped = True
 
    def tick(self):
        if (not self.stopped):
            self.timer = self.timer + 1
 
            #Loop
            if (self.timer % (self.tempo * self.end) == 0 and (not (self.timer == 0))):
                if (not self.looping):
                    self.stop()
                    return False
                self.beat = -1
                self.timer = 0
 
            #On Beat
            if (self.timer % self.tempo == 0):
                self.beat = self.beat + 1
 
                #Remove expired notes from playing list
                i = 0
                while (i < len(self.playingDurations)):
                    self.playingDurations[i] = self.playingDurations[i] - 1
                    if (self.playingDurations[i] <= 0):
                        self.playingNotes.pop(i)
                        self.playingDurations.pop(i)
                    else:
                        i = i + 1
 
                #Add new notes and their durations to the playing list
 
                """
                #Old method runs for every note, slow to process on every beat and causes noticeable delay
                ssong = song.split(";")
                for note in ssong:
                    snote = note.split(" ")
                    if int(snote[0]) == beat:
                        playingNotes.append(snote[1])
                        playingDurations.append(int(snote[2]))
                """
 
                if (self.beat < len(self.notes)):
                    if (self.notes[self.beat] != None):
                        for note in self.notes[self.beat]:
                            self.playingNotes.append(note[0])
                            self.playingDurations.append(note[1])
 
                #Only need to run these checks on beats
                i = 0
                for pwm in self.pwms:
                    if (i >= len(self.playingNotes)):
                        pwm.duty_u16(0)
                    else:
                        #Play note
                        pwm.duty_u16(self.duty)
                        pwm.freq(tones[self.playingNotes[i]])
                    i = i + 1
 
 
            #Play arp of all playing notes
            if (len(self.playingNotes) > len(self.pwms)):
                self.pwms[len(self.pwms)-1].duty_u16(self.duty)
                if (self.arpnote > len(self.playingNotes)-len(self.pwms)):
                    self.arpnote = 0
                self.pwms[len(self.pwms)-1].freq(tones[self.playingNotes[self.arpnote+(len(self.pwms)-1)]])
                self.arpnote = self.arpnote + 1
 
            return True
        else:
            return False

example.py

Find a piece of music on onlinesequencer.net, click edit, then select all notes with CTRL+A and copy them with CTRL+C Paste string as shown above after removing “;:” from the end and “Online Sequencer:120233:” from the start

from buzzer_music import music
from time import sleep
from machine import Pin
 
#One buzzer on pin 0
mySong = music(song, pins=[Pin(0)])
 
#Four buzzers
#mySong = music(song, pins=[Pin(0),Pin(1),Pin(2),Pin(3)])
 
while True:
    print(mySong.tick())
    sleep(0.04)