利用蜂鳴器唱歌
Description
2019-03-07
國立暨南國際大學 應用材料及光電工程學系 學士班一年級
作者:彭俊翔 林鼎祐 吳紹端 彭子瑜 蕭雅馨 蘇郁茹
指導教授:曹永忠 博士
利用蜂鳴器唱生日快樂歌給朋友聽
首先介紹一下甚麼是聲音,一般來說我們說話唱歌發出的都是聲音,聲音簡單的組成為兩項:
聲音的高低與聲音的大小,這個應該不用特別解說了,重點是電子訊號怎麼控制聲音的這兩項組成,聲音的大小不用說,靠的是通過的電壓高低,至於控制高低音,靠的是控制頻率。
要讓蜂鳴器唱歌基本上就是讓蜂鳴器可以產生不同頻率的聲音, Arduino 上只要用兩個指令:tone() / noTone() 就可以達到 (相關介紹可以看這裡)
Arduino 由指定的 pin 發出特定頻率(duty cycle = 50%,PWM 介紹看這裡)的方波一段時間控制蜂鳴器發出的聲音
tone(pin, frequency, duration)
pin:輸出方波訊號的 digital pin frequency (unsigned int):讓蜂鳴器發出的聲音的對應頻率 duration (unsigned long):發出聲音的長短
函數的參數說明:
pin: 你要接揚聲器的接口,是整數(int 型)
frequency:頻率,是一個整數(int 型)
duration: 音符持續的時間,是毫秒值,無符號長整型( unsigned long型)
這邊我在測試的時候發現一個問題,使用 tone() 的時候如果沒搭配 delay (duration) 聲音會亂掉
noTone (pin):將指定 pin 的聲音停止,Arduino 的缺點就是沒辦法讓兩之 pin 同時輸出,所以很可惜的沒辦法用 Arduino 做和絃~,當 pin2 發出聲音的時候要讓 pin3 發出聲音,要先 noTone (2) 停止 pin2 發出的訊號,不然不會有任何作用
下面我們回憶一下小時候音樂課學的頻率與音階的關係:
輸入 tone(2,262,1000),就可以讓接在 pin2 上的蜂鳴器發出 Do~ 的聲音 1 秒。
好了!我們可以讓蜂鳴器唱歌了!!
準備材料:
蜂鳴器x1
按照接線圖接線:
Sketch及說明:
首先我們要讓他唱的歌是生日快樂歌,簡譜如下:
int sing = 5;
// 依照簡譜的順序,填入代表的音符,空白代表休止符
char notes[] = “ggagCb ggagDC ggGECba FFECDC”;
// 決定每個音階的拍子,注意這邊用 unsigned long 所以拍子只能是正整數
unsigned long beats[] = {1,1,2,2,2,2,2,1,1,2,2,2,2,2,1,1,2,2,2,2,2,1,1,2,2,2,2,2,2};
// 利用 sizeof(),算出總共要多少音符
int length = sizeof(notes);
// 決定一拍多長,這邊一拍 300 ms
int tempo = 300;
void setup()
{
pinMode(sing, OUTPUT);
}
void loop(){
// 利用 for 來播放我們設定的歌曲,一個音一個音撥放
for (int i = 0; i < length; i++) {
// 如果是空白的話,不撥放音樂
if (notes[i] == ‘ ‘)
{
delay(beats[i] * tempo); // rest
}
else
{
// 呼叫 palyNote() 這個 function,將音符轉換成訊號讓蜂鳴器發聲
playNote(sing,notes[i], beats[i] * tempo);
}
// 每個音符之間的間隔,這邊設定的長短會有連音 or 段音的效果
delay(tempo/15);
}
}
void playNote(int OutputPin, char note, unsigned long duration)
{
// 音符字元與對應的頻率由兩個矩陣表示
char names[] = { ‘c’, ‘d’, ‘e’, ‘f’, ‘g’, ‘a’, ‘b’, ‘C’,’D’,’E’,’F’,’G’ };
int tones[] = { 262, 294, 330, 349, 392, 440, 494, 523,587,659,698,784 };
// 播放音符對應的頻率
for (int i = 0; i < 12; i++)
{
if (names[i] == note)
{
tone(OutputPin,tones[i], duration);
//下方的 delay() 及 noTone (),測試過後一定要有這兩行,整體的撥放出來的東西才不會亂掉,可能是因為 Arduino 送出tone () 頻率後會馬上接著執行下個指令,不會等聲音播完,導致撥出的聲音混合而亂掉
delay(duration);
noTone(OutputPin);
}
}
}
這邊要注意的是,因為 tone () 的時間只能整數,所以有半拍的音樂 beats = 0.5 是不會有動作的,建議就是直接將所有拍子 x2 去寫。
成果:
參考資源:
http://thats-worth.blogspot.com/2014/05/arduino-controlling-piezo.html
(MakerPRO 編輯部代發)
Contact
- CategoryArduino
- Tags暨大