拍手開關(guān)對于初學(xué)者來說是一個很有趣的單片機方案。它以拍手的聲音打開和關(guān)閉電器。在本文中,單片機開發(fā)工程師們將使用PIC單片機制作一個簡單的拍手開關(guān),當(dāng)它連續(xù)檢測到兩個拍手聲音時,該開關(guān)便會運行。在這個方案中,使用駐極體麥克風(fēng)作為換能器,將拍手聲轉(zhuǎn)換為電信號。麥克風(fēng)的輸出由晶體管放大,然后發(fā)送到PIC12F683單片機,當(dāng)檢測到有效拍手時,PIC12F683單片機執(zhí)行ON/OFF切換動作。
聲控拍手開關(guān)的原理
拍手開關(guān)的輸入端需要一個換能器,以將拍手的聲音振動轉(zhuǎn)換為電能。為此使用駐極體麥克風(fēng)或簡單的麥克風(fēng)(OBO-04FN-0B)。麥克風(fēng)的輸出中的聲音信號電流很低,因此我們需要一個放大器電路來增強檢測到的聲音信號。以下電路圖顯示了麥克風(fēng)和單個晶體管放大器。當(dāng)沒有聲音時,飽和的晶體管的集電極電壓(Vout)約為0.2V。當(dāng)麥克風(fēng)檢測到拍手聲時,其兩端的電壓突然下降。由于電容麥克風(fēng)的輸出電壓通過電容器C1耦合到晶體管的基極,因此基極-發(fā)射極電壓也降低了,因此基極-發(fā)射極結(jié)點的正向偏置較少。拍手時,可以看到峰值電壓可以高達(dá)4.0V,具體取決于拍手的響度。
我們將集電極輸出電壓(Vout)與內(nèi)部產(chǎn)生的參考電壓進行比較。參考電壓在內(nèi)部連接到比較器模塊的正輸入(CIN +),而傳感器的輸出電壓則饋送到比較器的負(fù)輸入(CIN-)。CIN-引腳與PIC12F683的GP1 I/O引腳復(fù)用。參考電壓的大小可通過VRCON寄存器進行編程和控制。我們將參考電壓設(shè)置為0.625V(假設(shè)電源電壓為5.0V)。因此,在正常情況下,參考電壓(0.625V)大于Vout(= 0.2V),比較器輸出(COUT)為高。COUT可通過GP2 I/O引腳在內(nèi)部和外部進行訪問。當(dāng)有拍手聲時,COUT會變低。通過將CMCON0寄存器中的比較器輸出反相(CIN)位置1,可以將比較器輸出邏輯反相?梢詫IC12F683單片機進行編程,以根據(jù)比較器輸出采取開關(guān)動作。
聲控拍手開關(guān)電路原理圖
這個簡單的拍擊開關(guān)方案的完整電路圖如下所示。內(nèi)部比較器模塊的正和負(fù)輸入分別可通過GP0/CIN +和GP1/CIN-引腳從外部訪問。由于正輸入連接到內(nèi)部基準(zhǔn)電壓源,因此GP1引腳可用作I/O引腳。傳感器放大器的輸出將到達(dá)GP0/CIN +引腳。LED連接到GP5引腳以指示單片機的開關(guān)動作。當(dāng)單片機連續(xù)檢測到兩個拍手聲時,它將在GP5引腳上切換邏輯輸出。LED在這里用于說明目的,如果您想用它來控制電器,可以用機電繼電器代替。
聲控拍手開關(guān)程序
該程序用C語言開發(fā),并使用MikroC Pro進行PIC編譯器編譯。程序以1.5秒的間隔連續(xù)尋找兩個拍手聲。如果發(fā)生這種情況,則將GP5引腳切換。當(dāng)檢測到拍手時,TImer1模塊將打開以保持時間記錄。 1.5秒后,它將生成一個超時信號。如果在此之前沒有第二個拍手,則單片機將忽略第一個拍手,并返回到主程序。
sbit Output_LED at GP5_bit;
unsigned short i, TIME_UP;
void interrupt(void){
if(PIR1.TMR1IF) {
i ++;
if(i == 3) TIME_UP = 1; // TIme Up in 1.5 sec
PIR1.TMR1IF = 0;
}
}
void main() {
TRISIO = 0b00000011 ;
ANSEL = 0x00;
INTCON = 0b11000000 ; // Enable GIE and PEIE for Timer1 overflow interrpt
PIE1 = 0b00000001 ; // Enable TMR1IE
// Configure Comparator module
// CIN- pin is configured as analog,
// CIN+ pin is configured as I/O,
// COUT pin is configured as I/O,
// Comparator output available internally,
// CVREF is non-inverting input
// CINV is set to 1
CMCON0 = 0b00010100;
VRCON = 0b10100011; // Vref is set to VDD/8
Output_LED = 0;
do{
TMR1H = 0x00;
TMR1L = 0x00;
TIME_UP = 0;
i = 0;
T1CON = 0b00110000; // Configure Timer 1
if(CMCON0.COUT){ // First clap detected
Delay_ms(100);
T1CON.TMR1ON = 1; // Start Timer1
while(!CMCON0.COUT && !TIME_UP); // Wait until second clap is
T1CON.TMR1ON = 0; // detected or Timer1 overflows
if(CMCON0.COUT && !TIME_UP) Output_LED = ~Output_LED;
Delay_ms(100);
}
} while(1);
}