iT邦幫忙

2023 iThome 鐵人賽

DAY 12
2
自我挑戰組

WiFiBoy Python 玩學機介紹系列 第 12

12. 遊戲音樂引擎展示

  • 分享至 

  • xImage
  •  

蜂鳴器發聲原理

玩學機內建了一個蜂鳴器(Buzzer),這堂課我們將要用這個發聲裝置來做一些有趣的應用。課程開始之前,我們先來了解蜂鳴器的構造與發聲原理。

蜂鳴器1

蜂鳴器2

蜂鳴器(Buzzer)是一種常見的聲音輸出設備,通常用於在嵌入式系統、電子設備和電子專案中產生聲音或音效。蜂鳴器通過振動產生聲音,發聲原理如下:

  1. 振動元件: 蜂鳴器的核心是一個振動元件,通常是由壓電陶瓷材料製成。壓電陶瓷具有壓電效應,當施加電場時,它會發生機械變形。
  2. 信號輸入: 蜂鳴器通過正極和負極連接到電路。當電壓施加到蜂鳴器的正負兩極時,電場會使振動元件發生微小的機械振動。
  3. 振動產生聲音: 當電場施加到蜂鳴器上時,壓電陶瓷材料會根據電場的極性發生微小的收縮和膨脹,導致振動元件振動。振動元件的振動在周圍空氣產生了壓縮和膨脹的波動,這些波動以聲音的形式傳播,產生音波。
  4. 聲音頻率控制: 蜂鳴器的聲音頻率取決於電場施加的頻率。通過以不同的頻率切換電場,可以產生不同音高的聲音。通常,蜂鳴器可以產生簡單的音調,例如蜂鳴聲、蜂鳴警報或簡單的音樂。

Micropython 中的聲音與玩學機音樂引擎簡介

如何用微控制器產生聲音

微控制器非常擅長在其GPIO引腳上生成數位輸出。這些數位信號可在零電壓和正電壓(如3.3伏或5伏)之間快速切換。但它們並非設計用來創建連續變化電壓的“類比”輸出。不過,我們可用一種稱為「脈衝寬度調製(Pulse Width Modulation)」的技術來只用數位輸出來模擬各種聲音頻率。

脈寬調製不是改變電信號的高度,而是改變數位信號脈衝之間的寬度的過程。通過改變數位信號之間的距離,我們可以生成一個聽起來像具有更高或更低頻率或音調的信號。

MicroPython提供了一個強大的函式庫,叫做 PWM,讓您輕鬆生成不同形狀的訊號。

工作週期(Duty Cycle) 是指脈衝高時的時間百分比。

Duty Cycle

讓玩學機發出聲音

音階

撥放單音

我們先用積木程式來教大家如何讓玩學機發出聲音。

積木程式

因此,我們聲音類的程式,都會使用文字程式來編寫。
PWM 是一種波形產生器,Pin#25 是接到 WiFiBoy 蜂鳴器的 IO 輸出線路。設定聲音發出頻率440Hz,鋼琴中間的La (A) 通常是440 Hz。每高八度音,頻率就增加一倍,高八度的 La 就是 880Hz,低八度的 La 就是 220Hz。 snd.duty(100) 設定聲音能量強度為 100 ,也就是把蜂鳴器聲音開到最大。snd.duty(0),就是把聲音關掉。音樂撥放完畢後,要記得要用 snd.deinit() 關閉 PWM 物件。

from machine import Pin, PWM
from utime import sleep
snd_PIN = Pin(17, 2).value(1)			# 啟動聲音輸出腳位
snd = PWM(Pin(25, 2))					# 建立在 25腳位的 PWM 物件
snd.duty(0)

def play(f, t):
    snd.freq(f)						    # 設定撥放的聲音頻率
    snd.duty(50)						# 設定工作週期為 50%
	time.sleep(t)						# 暫停 t 秒
	snd.duty(0)						    # 關閉工作週期
 
play(880, 0.2)
play(440, 0.2)
play(220, 0.2)
snd.deinit()

應用範例

演奏音階

from machine import Pin, PWM
from utime import sleep

# 設定
snd_PIN = Pin(17,2).value(1)
snd = PWM(Pin(25,2))
ON_TIME = .25
OFF_TIME = .1

def play(freq, t):
    snd.duty(50)
    snd.freq(freq)
    sleep(t)
    snd.duty(0)
    
# 演奏音階
freq = 30
for i in range(64):
    print(freq)
    play(freq, 0.2)
    freq = int(freq * 1.15)

snd.deinit()                # 關閉 PWM

音頻對照表

我們參考英文維基百科條目「Scientific_pitch_notation」,讓學員可以從這張對照表快速知道 88 鍵的鋼琴,每個琴鍵對應的頻率值,這樣我們未來編寫程式時,才不用背一大堆數字。

88鍵

對照表

如果您要更進一步認識「音階標準頻率」的相關知識,可以參考「https://www.youtube.com/watch?v=czGQiTHaffM」這個教學影片,專文「震動噪音科普專欄_音階標準頻率」介紹連結在「http://aitanvh.blogspot.com/2018/03/blog-post_19.html」。

有了這兩張表,我們再來看內建的 toneng 聲音引擎文件就會比較容易看懂。

玩學機內建音調引擎,使用簡譜系統演奏

請輸入 help(toneng),您會看到底下的輸出結果。

>>> help(toneng)
object <module 'toneng' from 'toneng.py'> is of type module
  __file__ -- toneng.py
  __name__ -- toneng
  freqlist -- [110, 117, 123, 131, 139, 147, 156, 165, 175, 185, 196, 208, 220, 233, 247, 262, 277, 294, 311, 330, 349, 370, 392, 415, 440, 466, 494, 523, 554, 587, 622, 659, 698, 740, 784, 831, 880, 932, 988, 1047, 1109, 1175, 1245, 1319, 1397, 1480, 1568, 1661, 1760, 1865, 1976, 2093, 2217, 2349, 2489, 2637, 2794, 2960, 3136, 3322, 3520, 3729, 3951, 4186, 4435, 4699, 4978, 5274, 5588, 5920, 6272, 6645, 7040, 7459, 7902, 8372, 8870, 9397, 9956, 10548, 11175, 11840, 12544, 13290, 14080, 14917, 15804, 16744]
  counter -- 0
  play -- <function play at 0x3ffe6290>
  playing -- 0
  ndutyd -- 5
  _tempo -- 80
  initduty -- 100
  tempo -- <function tempo at 0x3ffe62a0>
  machine -- <module 'umachine'>
  _snd -- PWM(Pin(25), freq=880, duty=0, resolution=16, (duty=0.00%, resolution=0.002%), mode=0, channel=0, timer=0)
  _ps -- 
  nduty -- -300
  octave -- 3
  ps -- <function ps at 0x3ffe62b0>
  tone -- Timer(3ffe61b0; alarm_en=1, auto_reload=1, counter_en=1)
  toneEngine -- <function toneEngine at 0x3ffe62c0>
  1. toneng.freqlist : 內建的頻率列表,也就是內建的音階。從頻率110(A2)開始到 16744(C10)為止。
  2. 我們可以把樂譜編成 toneng 引擎認得的形式,送進 toneng._ps 讓音樂引擎自動播音樂。
  3. 這是「告白氣球」的音樂片段 "G>C<BGCC2GDDEFEE2.G>C<BCC2GDDEFEE2.G>DCCC2DEECC2CC<GG2GFEDDCCDD1.."

玩學機內建音調引擎,使用簡譜系統演奏

import toneng					# 匯入 toneng 音效引擎
# 輸入小蜜蜂簡譜
ps = "GEE2FDD2CDEFGGG2GEE2FDD2CEGGC1DDDDDEF2EEEEEFG2GEE2FDD2CEGGC1" # 小蜜蜂
toneng._ps = ps				# 送入 toneng._ps 執行

謝謝各位讀者還能堅持到現在,明日我們要來介紹「使用超音波感測器作測距儀」。


上一篇
11. 讓 LED 燈環顯示
下一篇
13. 使用超音波感測器作測距儀
系列文
WiFiBoy Python 玩學機介紹30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言