1. 程式人生 > >Arduino+蜂鳴器製作有趣的小音樂

Arduino+蜂鳴器製作有趣的小音樂

Arduino相關姿勢

Arduino是一個開源的硬體平臺,包括開發套組(開發板和相關的模組以及連線)和IDE,開發語言基於C。核心是一塊8位ATmega328的處理器,這塊處理器是AVR微控制器系列的高檔產品。Arduino提供了數字介面和模擬訊號口,還有擴充套件口便於進行設計。開發板通電後可以產生5V和3.3V電壓。

蜂鳴器

根據發聲原理不同分為電壓式蜂鳴器和電磁式蜂鳴器。我們使用的是電磁式蜂鳴器,接通電源後,振動膜片週期性的振動發聲。需要注意的一點是,發聲是在內部有電流產生磁場,使得膜片振動的一瞬間。 如果內部一直是直流電的話我們只能聽到很小的一下的聲音,如果需要持續的聲音(就像我萌以前過生日的那種唱生日快樂歌的小玩意)應該怎麼辦呢?BINGO!需要一個交流的驅動電路就行。最簡單的方波就可以驅動。

這裡我們使用的是無源蜂鳴器, 這裡的源指的是振盪源,自帶BUFF的就是有源,也就是直接同直流電就可以發聲,無源則需要外部送入方波訊號用於驅動才行。

硬體連線

連線很簡單,直接將正負極分別接入數字IO和GND就可以。如果覺得聲音太大的話可以串聯一個1K左右的電阻(具體取決於你的蜂鳴器額定電壓)。

Arduino連線蜂鳴器

讓蜂鳴器響起來

前面我們已經把數字IO連線到了蜂鳴器的正極,讓蜂鳴器響起來只需要在數字IO上放入方波即可。

digitalWrite(buzzerPin,HIGH); //高電平
delay(100);
digitalWrite(buzzerPin,LOW);  //低電平
delay(100
)
;

其中的100指的是100ms,這樣算來通電(高電平)佔空比就是50%,週期200ms,那麼頻率就是500Hz,這個頻率實際上已經比較高了。

不同的旋律

原理

如果只是這樣的話,只能簡單的發出警報一類的聲音吧?如果要發出精確的不同頻率的樂音怎麼辦?難道還要算?

一個人算

好吧,那我萌肯定知道不同的樂音有著不同的頻率,這裡貼一張樂音訊率圖。
這裡寫圖片描述

在Arduino中我們使用tone()函式就可以實現發出樂音的效果,可以參考這個連結

方法

實現音樂有兩個基本的要素,第一是音符,剛才我萌已經搞定了;第二是節奏,也就是拍子,或者說音符時值。之前的delay()函式可以用於延長這個音,因此我們如果規定四分音符的時延,編寫一個時延陣列就可以控制延長的時間。

值得注意的是,delay()函式的引數是unsigned long,因此四分音符的時延基數不妨設定為偶數,這樣其他的音符就可以減半和加倍。如果沒有太多連音和更小時值的音符,那麼這樣做就很方便。

Code

演奏小星星大家都會啦,這裡放一曲很喜歡的CLANNAD的《潮鳴》的小的段落程式碼,算作這一次小專案的禮物~(~ ̄▽ ̄)~

/**
 * 使用Buzzer演奏潮鳴
 * @author Mr.Bubbles
 * 1=C
 */
#include "music_note.c" //音符表

int buzzer=3; //蜂鳴器口,PWM
int scale[]={G,A,EE,A,G,A,G,A,EE,A,G,
             A,EE,A,G,A,E,
             G,D,E,G,A,B,
             A,EE,A,G,A,G,
             A,EE,B,CC,B,CC,B,A,E,
             D,E,G,A,B,A,EE,A,G,A,
             G,A,EE,A,G,A,EE,A,G,A,
             E,G,D,E,G,A,B,A,EE,A,G,A,
             G,A,EE,B,CC,B,CC,DD,EE,AA};  //旋律
float duration[]={2,1,1,1,1,7,1,1,1,1,1,
                  1,1,1,1,3,1,
                  3,1,1,1,1,1,
                  1,1,1,1,7,1,
                  1,1,1,1,1,1,1,1,6,
                  1,1,1,1,1,1,1,1,1,7,
                  1,1,1,1,1,1,1,1,1,3,
                  1,3,1,1,1,1,1,1,1,1,1,7,
                  1,1,1,1,1,1,1,1,1,4}; //音符時值 
int len=0;  //該變數後面用於統計音符個數               
void setup() {
  pinMode(buzzer,OUTPUT);
  len=sizeof(scale)/sizeof(scale[0]);
}

void loop() {
  for(int i=0;i<len;i++){ 
    tone(buzzer,scale[i]);
    delay(250*duration[i]);
    noTone(buzzer);
    delay(100);
  }
  delay(1000);
}

Git Repository

Reference