☛ 功能說明

利用 Arduino UNO 開發板播放兩首鋼琴入門音樂 – 小蜜蜂 ( Little Bee ) 及小星星 ( Little Star )。並使用一個 TACK 按鍵開關 SW,開機時預設為靜音,每按一次按鍵開關 SW,可以切換小蜜蜂 ( Little Bee )、小星星 ( Little Star ) 及靜音等三種選擇,演奏速度為每分鐘 180 拍。

☛ 使用材料

Arduino UNO R3 開發板 × 1、10 μF/16V 電容 × 1、 喇叭或蜂鳴器 × 1、TACK 按鍵開關 SW × 1。

☛ 電路圖及麵包板接線圖

☛ 程式碼

const int speaker  = 2;                              // 數位接腳 2 連接喇叭
const int sw       = 3;                              // 數位接腳 3 連接按鍵開關
const int debounce = 20;                             // 消除彈跳時間 20ms
char  toneName[]   = "CDEFGAB";                      // 音符表
unsigned int frequency[7] =                          // 頻率表
             { 523, 587, 659, 694,
               784, 880, 988 };
char beeTone[] = "GEEFDDCDEFGGGGEEFDDCEGGEDDDDDEFEEEEEFGGEEFDDCEGGC";
char starTone[]= "CCGGAAGFFEEDDCGGFFEEDGGFFEEDCCGGAAGFFEEDDC";
byte beeBeat[] = { 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2,       // 小蜜蜂節拍
                   1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 4, 1, 1,
                   1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1,
                   1, 2, 1, 1, 2, 1, 1, 1, 1, 4 };
byte starBeat[]= { 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1,       // 小星星節拍
                   2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1,
                   1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1,
                   1, 1, 2 };
unsigned long tempo = 180;                           // 每分鐘 180 拍
const int beeLen = sizeof(beeTone);                  // 小蜜蜂音符總數
const int starLen= sizeof(starTone);                 // 小星星音符总数
int len          = 0;                                // 尚未演奏的剩餘音符
int num;                                             // 音符指標
int keyVal       = 0;                                // 鍵值

void setup()
{
     pinMode(sw, INPUT_PULLUP);                      // 設定數位接腳 3 為輸入模式
}

void loop()
{
     if(digitalRead(sw)==0)                          // 按下按鍵?
     {
        delay(debounce);                             // 消除按鍵機械彈跳
        while(digitalRead(sw)==0)                    // 按下按鍵?
              ;                                      // 按鍵已放開
        keyVal++;                                    // 鍵值加 1
        if(keyVal>2)                                 // 鍵值大於 2?
           keyVal = 0;                               // 清除鍵值
        num=0;                                       // 從第一個音符開始播放
        if(keyVal==1)                                // 鍵值為 1?
           len = beeLen;                             // 取出小蜜蜂音符總數
        else if(keyVal==2 )                          // 鍵值為 2?
                len = starLen;                       // 取出小星星音符總數
     }

     if(keyVal==1 && len>0)                          // 鍵值為 1 且 len>0?
     {
        playTone(beeTone[num], beeBeat[num]);        // 播放一個音符
        num++;                                       // 下一個音符
        len--;                                       // 長度減一
     }
     else if(keyVal==2 && len>0)                     // 鍵值為 2 且 len>0?
     {
        playTone(starTone[num], starBeat[num]);      // 播放一個音符
        num++;                                       // 下一個音符
        len--;                                       // 長度減一
     }
}

void playTone(char toneNo, byte beatNo)              // 播放音符函式
{
     unsigned long duration = beatNo*60000 / tempo;  // 計算每拍時間 ( 毫秒 )
     int i;
     for(i=0;i<7;i++)
     {
         if(toneNo==toneName[i])                     // 查音符表
         {
            tone(speaker,frequency[i]);              // 播放音符
            delay(duration);                         // 此音符的節拍
            noTone(speaker);                         // 關閉聲音
         }
     }
}

 

☛ 練習

⑴ 設計 Arduino 程式,使用一個 TACK 按鍵開關 SW,控制播放兩首鋼琴入門音樂 – 小蜜蜂 ( Little Bee ) 和小星星 ( Little Star ),同時使用 LED 顯示播放的音符。

const int speaker  = 2;                              // 數位接腳 2 連接喇叭
const int sw       = 3;                              // 數位接腳 3 連接按鍵開關
const int debounce = 20;                             // 消除彈跳時間 20ms
char  toneName[]   = "CDEFGAB";                      // 音符表
unsigned int frequency[7] =                          // 頻率表
             { 523, 587, 659, 694,
               784, 880, 988 };
char beeTone[] = "GEEFDDCDEFGGGGEEFDDCEGGEDDDDDEFEEEEEFGGEEFDDCEGGC";
char starTone[]= "CCGGAAGFFEEDDCGGFFEEDGGFFEEDCCGGAAGFFEEDDC";
byte beeBeat[] = { 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2,       // 小蜜蜂節拍
                   1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 4, 1, 1,
                   1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1,
                   1, 2, 1, 1, 2, 1, 1, 1, 1, 4 };
byte starBeat[]= { 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1,       // 小星星節拍
                   2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1,
                   1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1,
                   1, 1, 2 };
unsigned long tempo = 180;                           // 每分鐘 180 拍
const int beeLen = sizeof(beeTone);                  // 小蜜蜂音符總數
const int starLen= sizeof(starTone);                 // 小星星音符總數
int len          = 0;                                // 尚未演奏的剩餘音符
int num;                                             // 音符指標
int keyVal       = 0;                                // 鍵值
int led[6] = { 4, 5, 6, 7, 8, 9 };                   // 數位接腳 4 ~ 9 連接 6 個 LED
void setup()
{
     pinMode(sw, INPUT_PULLUP);                      // 設定數位接腳 3 為輸入模式
     for(int i=0;i<7;i++)
         pinMode(led[i],OUTPUT);                     // 設定數位接腳 4 ~ 9 為輸出模式
}

void loop()
{
     if(digitalRead(sw)==0)                          // 按下按鍵?
     {
        delay(debounce);                             // 消除按鍵機械彈跳
        while(digitalRead(sw)==0)                    // 按下按鍵?
              ;                                      // 按鍵已放開
        keyVal++;                                    // 鍵值加 1
        if(keyVal>2)                                 // 键值大于 2?
           keyVal = 0;                               // 清除鍵值
        num=0;                                       // 從第一個音符開始播放
        if(keyVal==1)                                // 鍵值為 1?
           len = beeLen;                             // 取出小蜜蜂音符總數
        else if(keyVal==2 )                          // 鍵值為 2?
                len = starLen;                       // 取出小星星音符總數
     }

     if(keyVal==1 && len>0)                          // 鍵值為 1 且 len>0?
     {
        playTone(beeTone[num], beeBeat[num]);        // 播放一個音符
        num++;                                       // 下一個音符
        len--;                                       // 長度減一
     }
     else if(keyVal==2 && len>0)                     // 鍵值為 2 且 len>0?
     {
        playTone(starTone[num], starBeat[num]);      // 播放一個音符
        num++;                                       // 下一個音符
        len--;                                       // 長度減一
     }
}

void playTone(char toneNo, byte beatNo)              // 播放音符函式
{
     unsigned long duration = beatNo*60000 / tempo;  // 計算每拍時間 ( 毫秒 )
     int i;
     for(i=0;i<7;i++)
     {
         if(toneNo==toneName[i])                     // 查音符表
         {
            tone(speaker,frequency[i]);              // 播放音符
            digitalWrite(led[i],HIGH);               // 點亮音符對應的 LED
            delay(duration);                         // 此音符的節拍
            noTone(speaker);                         // 關閉聲音
            digitalWrite(led[i],LOW);                // 熄滅音符對應的 LED
         }
     }
}