2015年10月24日 星期六

ROSA 系統開發 10 ─ 蜂鳴器 (Buzzer)

http://4rdp.blogspot.com/2015/10/rosa-10-buzzer.html?m=0

蜂鳴器在嵌入式系統中,是很常見的硬體裝置,因為它可以發出聲音,提示操作者目前系統的狀態,本文將說明如何加入蜂鳴器功能。

// (C) 2015, Bridan Wang, CC BY-NC-SA 3.0 TW
// http://4rdp.blogspot.tw/search/label/ROSA%20(Arduino)

// pin 8    Buzzer
#include "MeBuzzer.h"
MeBuzzer buzzer;

byte pitch = 0;
const PITCH[] = {
  // C    C#   D    D#   E    F    F#   G    G#   A    A#   B
  0, 131, 139, 147, 156, 165, 175, 185, 196, 208, 220, 233, 247,
};

// pin 2,3   IR
#include "MeIR.h"
MeIR ir;


const byte IR_CODE[][13] = {
  //X,  1,  2,  3,  4,  5,  6,  7,  A,  B,  C,  D,  E, 
    0, 12, 24, 94,  8, 28, 90, 66, 69, 70, 71, 68, 67, 
    0,  1,  3,  5,  6,  8, 10, 12,  7,  9, 11,  2,  4, 
};

void IR_CHECK() {   // for mBot car
  static byte sound = 0;
  static byte pre_ir;
  byte i;
  byte j;
  if (sound != 0){
    if (--sound == 0) {
      buzzer.noTone();
      ir.loop();
    }
  } 
  if (sound==0) {
    j = ir.key();
    for (i = 12; i<13; i--) {
      if (j == IR_CODE[0][i] && pre_ir != j) {
pre_ir = j;
if (i==0)
         ;
else {
         pitch = IR_CODE[1][i];
         buzzer.tone(PITCH[pitch]);
         sound = 2;    // 2 x 100ms
         // Serial.print("IR - ");
         // Serial.println(pitch);
}
break;
      }
    }
  }
  if (sound == 0)
    ir.loop();
}

這個程式範例蜂鳴器接在 pin 8,仿電子琴以遙控器 1~7 按鍵代表 Do,Re,Mi...,ABCDE 分別表示升半音 4#,5#,6#,1#,2#,這樣可以演奏簡單的樂譜。

為了程式能更進一步接近未來 ROSA 系統架構,將 ROSA系統開發4─紅外線接收遙控的 IR_CHECK 內容再改寫,以查表方式設計。IR_CODE 陣列第一行是 mBot 紅外線遙控碼,第二行是對應音高的指標數值。舉例來說,當按下遙控器 6 鍵,它的控制碼是 90,經過 IR_CHECK 副程式查表,pitch 索引為 10,對應 PITCH 陣列 A 的位置。

IR_CHECK 程式設計複雜的主因在於 MeBuzzer.h 及 MeIR.h 兩函式庫共用 Timer 2 中斷,如果處理不好,不是遙控器失效,不然就蜂鳴器無聲或聲音不停。首先說明,IR_CHECK 宣告一個 pre_ir 變數用來儲存前次紅外線碼,它可以避免紅外線連續重複送碼,致使蜂鳴器聲音異常,sound 變數是用來計數蜂鳴器聲音長度,經過試驗發聲時間過短不好聽,因此採用短音 200ms 比較適中,不過紅外線碼讀取是每 100ms 一次,因此蜂鳴器發聲期間,就略過紅外線遙控動作檢查。

PITCH 陣列儲存各個音高的頻率,buzzer.tone()設定發音,buzzer.noTone()關閉 Timer 2 中斷,然後 Timer 2 主控權就可以還給紅外線接收 ir.loop(),如果不使用 MeBuzzer.h 而改用 Arduino 常見的 tone(),那程式編譯時會與 MeIR.h Timer 2 產生衝突,因此個人比較推薦採用此法,才能讓諸多程式庫相容無害。

沒有留言:

張貼留言