蜂鳴器在嵌入式系統中,是很常見的硬體裝置,因為它可以發出聲音,提示操作者目前系統的狀態,本文將說明如何加入蜂鳴器功能。
// (C) 2015, Bridan Wang, CC BY-NC-SA 3.0 TW
// http://4rdp.blogspot.tw/search/label/ROSA%20(Arduino)
// http://4rdp.blogspot.tw/search/label/ROSA%20(Arduino)
// pin 8 Buzzer
#include "MeBuzzer.h"
MeBuzzer buzzer;
byte pitch = 0;
byte pitch = 0;
const PITCH[] = {
// C C# D D# E F F# G G# A A# B
// 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;
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();
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();
為了程式能更進一步接近未來 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 產生衝突,因此個人比較推薦採用此法,才能讓諸多程式庫相容無害。
沒有留言:
張貼留言