有源蜂鸣器和无源蜂鸣器的区别:外形不同、测试声音不同、对输入信号的要求不同、有无震荡源、价格不同、高度不同、万用表测电阻不同、直流电压测试不同、优点不同。
外形不同
两种蜂鸣器的引脚郡朝上放置时,可以看出有绿色电路板的一种是无源蜂鸣器,没有电路板而用黑胶封闭的一种是有源蜂鸣器。
对输入信号的要求不同
有源蜂鸣器工作的理想信号是直流电,通常标示为VDC、VDD等。因为蜂鸣器内部有一简单的振荡电路,能将恒定的直流电转化成一定频率的脉冲信号,从面实出磁场交变,带动钼片振动发音。但是在某些有源蜂鸣器在特定的交流信号下也可以工作,只是对交流信号的电压和频率要求很高,此种工作方式一般不采用。而无源蜂鸣器没有内部驱动电路,有些公司和工厂称为讯响器,国标中称为声响器。无源蜂鸣器工作的理想信号方波。如果给预直流信号蜂鸣器是不响应的,因为磁路恒定,钼片不能振动发音。
有无震荡源
有源蜂鸣器内部带震荡源,所以只要一通电就会叫,而无源内部不带震荡源,所以如果用直流信号无法令其鸣叫。
无源蜂鸣器的优点是:便宜,声音频率可控,可以做出多来米发索拉西的效果,在一些特例中,可以和LED复用一个控制口。有源蜂鸣器的优点是:程序控制方便。
接线
蜂鸣器模块的 VCC 接树莓派 Pico 的 VSYS 引脚;蜂鸣器模块的 GND 接树莓派 Pico 的 GND 引脚;蜂鸣器模块的 I/O 引脚接树莓派 Pico 的 GP22 引脚。
编程
树莓派 Pico 通过 PWM 来驱动无源蜂鸣器发出不同频率的声音。我们直接使用现成的 Python 库 buzzer_music,该库可以方便的实现音乐乐谱播放。
将下面的代码保存在 Pico 上,命名为 buzzer_music.py。
""" Micropython (Raspberry Pi Pico) Plays music written on onlinesequencer.net through a passive piezo buzzer. Uses fast arpeggios with a single buzzer to simulate polyphony Also supports multiple buzzers at once for real polyphony https://github.com/james1236/buzzer_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
接下来就是导入乐谱,并进行播放了。下面我找到了一段 FC 红白机上「超级玛丽」游戏的 BGM 的乐谱。将下面的代码保存在 Pico 上,命名为 main.py。
from buzzer_music import music from time import sleep # 超级玛丽 BGM 乐谱 song = '0 E5 1 0;0 F#4 1 0;0 D4 1 0;2 E5 2 0;2 D4 2 0;6 E5 2 0;6 D4 2 0;10 D4 1 0;10 F#4 1 0;10 C5 1 0;2 F#4 2 0;6 F#4 2 0;12 E5 2 0;12 F#4 2 0;12 D4 2 0;16 G5 2 0;16 G4 2 0;16 B4 2 0;23 G4 2 0;23 G4 2 0;30 C5 3 0;30 E4 3 0;30 G4 3 0;36 G4 1 0;36 C4 1 0;36 E4 1 0;42 E4 3 0;42 G3 3 0;42 C4 3 0;48 A4 2 0;48 F4 2 0;48 C4 2 0;52 B4 2 0;52 G4 2 0;52 D4 2 0;58 A4 2 0;58 C4 2 0;58 F4 2 0;56 A#4 1 0;56 F#4 1 0;56 C#4 1 0;62 C4 3 0;62 G4 3 0;62 E4 3 0;65 G4 3 0;65 E5 3 0;65 C5 3 0;68 E5 3 0;68 G5 3 0;68 B4 3 0;71 A5 2 0;71 C5 2 0;71 F5 2 0;75 D5 1 0;77 E5 2 0;75 A4 1 0;77 B4 2 0;75 F5 1 0;77 G5 2 0;81 E5 2 0;81 A4 2 0;81 C5 2 0;85 E4 1 0;85 C5 1 0;85 A4 1 0;87 F4 1 0;87 B4 1 0;87 D5 1 0;89 B4 1 0;89 G4 1 0;89 D4 1 0;95 C5 3 0;95 E4 3 0;95 G4 3 0;101 G4 1 0;101 C4 1 0;101 E4 1 0;107 E4 3 0;107 G3 3 0;107 C4 3 0;113 A4 2 0;113 F4 2 0;113 C4 2 0;117 B4 2 0;117 G4 2 0;117 D4 2 0;123 A4 2 0;123 C4 2 0;123 F4 2 0;121 A#4 1 0;121 F#4 1 0;121 C#4 1 0;127 C4 3 0;127 G4 3 0;127 E4 3 0;130 G4 3 0;130 E5 3 0;130 C5 3 0;133 E5 3 0;133 G5 3 0;133 B4 3 0;136 A5 2 0;136 C5 2 0;136 F5 2 0;140 D5 1 0;142 E5 2 0;140 A4 1 0;142 B4 2 0;140 F5 1 0;142 G5 2 0;146 E5 2 0;146 A4 2 0;146 C5 2 0;150 E4 1 0;150 C5 1 0;150 A4 1 0;152 F4 1 0;152 B4 1 0;152 D5 1 0;154 B4 1 0;154 G4 1 0;154 D4 1 0;159 C4 4 0;162 G5 1 0;162 E5 1 0;164 F#5 1 0;164 D#5 1 0;164 G4 1 0;166 F5 1 0;166 D5 1 0;168 D#5 2 0;168 B4 2 0;172 E5 2 0;172 C5 2 0;176 G#4 1 0;176 E4 1 0;178 F4 1 0;178 A4 1 0;180 G4 2 0;180 C5 2 0;184 A4 1 0;184 C4 1 0;186 C5 1 0;188 F4 1 0;188 D5 1 0;170 C5 2 0;174 F4 2 0;182 C5 1 0;186 E4 1 0;190 C4 3 0;207 F5 2 0;207 G5 2 0;207 C6 2 0;211 F5 1 0;211 G5 1 0;211 C6 1 0;213 F5 2 0;213 G5 2 0;213 C6 2 0;217 G4 2 0;221 C4 3 0;193 G5 1 0;193 E5 1 0;195 F#5 1 0;195 D#5 1 0;195 G4 1 0;197 F5 1 0;197 D5 1 0;199 D#5 2 0;199 B4 2 0;203 E5 2 0;203 C5 2 0;224 G5 1 0;224 E5 1 0;226 F#5 1 0;226 D#5 1 0;226 G4 1 0;228 F5 1 0;228 D5 1 0;230 D#5 2 0;230 B4 2 0;234 E5 2 0;234 C5 2 0;240 F4 1 0;238 E4 1 0;238 G#4 1 0;240 A4 1 0;242 G4 2 0;242 C5 2 0;246 C4 1 0;246 A4 1 0;248 E4 1 0;248 C5 1 0;250 D5 1 0;250 F4 1 0;256 D#5 3 0;256 G#4 3 0;262 D5 1 0;262 F4 1 0;267 E4 2 0;267 C5 2 0;252 C4 1 0;273 G4 1 0;275 G4 2 0;279 D4 2 0;283 C4 4 0;286 G5 1 0;286 E5 1 0;288 F#5 1 0;288 D#5 1 0;288 G4 1 0;290 F5 1 0;290 D5 1 0;292 D#5 2 0;292 B4 2 0;296 E5 2 0;296 C5 2 0;300 G#4 1 0;300 E4 1 0;302 F4 1 0;302 A4 1 0;304 G4 2 0;304 C5 2 0;308 A4 1 0;308 C4 1 0;310 C5 1 0;312 F4 1 0;312 D5 1 0;294 C5 2 0;298 F4 2 0;306 C5 1 0;310 E4 1 0;314 C4 3 0;331 F5 2 0;331 G5 2 0;331 C6 2 0;335 F5 1 0;335 G5 1 0;335 C6 1 0;337 F5 2 0;337 G5 2 0;337 C6 2 0;317 G5 1 0;317 E5 1 0;319 F#5 1 0;319 D#5 1 0;319 G4 1 0;321 F5 1 0;321 D5 1 0;323 D#5 2 0;323 B4 2 0;327 E5 2 0;327 C5 2 0;341 G4 2 0;345 C4 3 0;348 G5 1 0;348 E5 1 0;350 F#5 1 0;350 D#5 1 0;350 G4 1 0;352 F5 1 0;352 D5 1 0;354 D#5 2 0;354 B4 2 0;358 E5 2 0;358 C5 2 0;364 F4 1 0;362 E4 1 0;362 G#4 1 0;364 A4 1 0;366 G4 2 0;366 C5 2 0;370 C4 1 0;370 A4 1 0;372 E4 1 0;372 C5 1 0;374 D5 1 0;374 F4 1 0;380 D#5 3 0;380 G#4 3 0;386 D5 1 0;386 F4 1 0;391 E4 2 0;391 C5 2 0;376 C4 1 0;397 G4 1 0;399 G4 2 0;403 D4 2 0;407 C5 1 0;407 G#4 1 0;409 A4 2 0;409 C5 2 0;413 A4 2 0;413 C5 2 0;407 G#3 3 0;413 E4 1 0;417 C5 1 0;417 G#4 1 0;419 C#5 2 0;419 A#4 2 0;423 E5 1 0;423 G4 1 0;425 C5 2 0;425 E4 2 0;429 E4 1 0;429 A4 1 0;431 G4 2 0;431 C4 2 0;438 C5 1 0;438 G#4 1 0;440 C5 2 0;440 A4 2 0;444 C5 2 0;444 A4 2 0;448 C5 1 0;459 G4 2 0;463 C5 1 0;463 G#4 1 0;465 A4 2 0;465 C5 2 0;469 A4 2 0;469 C5 2 0;463 G#3 3 0;469 E4 1 0;473 C5 1 0;473 G#4 1 0;475 C#5 2 0;475 A#4 2 0;479 E5 1 0;479 G4 1 0;481 C5 2 0;481 E4 2 0;485 E4 1 0;485 A4 1 0;487 G4 2 0;487 C4 2 0;454 G4 2 0' """ 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 machine import Pin mySong = music(song, pins=[Pin(22)]) #Four buzzers #mySong = music(song, pins=[Pin(0),Pin(1),Pin(2),Pin(3)]) while True: mySong.tick() sleep(0.03)
给树莓派 Pico 上电之后,音乐会开始播放。
发表评论