Arduino 聲控開關
這樣敘述太沒個人特色,所以我將其命名為28開關,哈哈.
以下就以28開關為名稱來描述.
介紹視訊
控制方式
1. 先拍手2下,若28開關有聽到會讓喇叭嗶一聲.
2. 此時環境因須保持安靜, 等28開關回應嗶二聲.
3. 再拍手1下
4. 此時環境因須保持安靜, 等28開關回應嗶三聲.
5. 再拍手1下. 開關即會開或關
特色
1. 採用多重指令,防止28開關因環境音影響而誤動作.
2. 內含簡易的適應性控制,讓開關即使在環境音影響下,不會誤動作外,仍可進行操作.
給誰看的
本篇是寫給對28開關(聲控開關)有興趣,單純想動手做做玩玩看的朋友們.不須具備電子電路設計的能力,不須會撰寫程式的技巧.只需一點耐心,然後按照下列步驟,就可以擁有一個好玩的聲控開關囉.
步驟
1.準備材料
2.連接測試電路
3.上傳程式到裝置
4.連接開關電路
1.準備材料
2.連接測試電路
3.上傳程式到裝置
4.連接開關電路
準備材料
1. Arduino Nano主控板x1(最好購買有Pin針的,這樣在線路配線時就可以用杜邦線直接插一插就好.)
1. Arduino Nano主控板x1(最好購買有Pin針的,這樣在線路配線時就可以用杜邦線直接插一插就好.)
2. Arduino 麥克風模組x1
3. Arduino 繼電器模組x1
4. 蜂鳴器x1
5. LED燈x1
6. Hi-Link 110V to 5V 電源模組
7. 杜邦線
以上皆為露x拍賣上即可取的的材料.為防廣告嫌疑,就不另提供相關網址了.
利用上述關鍵字即可搜尋到.
連接測試電路
蒐集好材料後,按照下面測試電路圖,利用杜邦線將配線接好.之後即可開始驗證
蒐集好材料後,按照下面測試電路圖,利用杜邦線將配線接好.之後即可開始驗證
上傳程式到裝置
要將程式上傳至裝置,需透過Arduino IDE這套軟體.
要將程式上傳至裝置,需透過Arduino IDE這套軟體.
我的程式是用Arduino IDE 1.6.8開發的,所以為防止相容性問題,請下載跟我同版本的IDE.
下載Arduino IDE
首先至Arduino官網https://www.arduino.cc/.
點選SOFTWARE,如下圖.
首先至Arduino官網https://www.arduino.cc/.
點選SOFTWARE,如下圖.
然後選擇以前的版本,如下圖.
找到1.6.8版,下載,並安裝.如下圖.
程式原始碼部份
// 28 Switch base on Arduino Nano
// Ver G4 // Date 2017-03-28 // Author: 30sec studio // #include "SoftwareSerial.h" #define HITSEC 500 // 拍手間格秒數 < HITSEC
#define TRIGGERSEC 400 // 觸發後等待秒數 < TRIGGERSEC #define TRIGGERVAL 15 // dB > 15開始取樣 #define TRIGGERMIN 5 // dB需低於 < 5 #define KEEPTIME 300 // 持續安靜300msec #define MIC A0
#define LED A1 // A2- #define BEEP A3 // A4- #define RELAY 2
#define RELAYB 7 SoftwareSerial Serial2(3, 4); // RX, TX
SoftwareSerial Serial3(5, 6); // RX, TX int iSoundVal, iLED, iRelay, iStep, iAvgIp, iBlink;
int iDifference, iLoKeep; int iEMax, iEKeep; float fAvg, fdB;
int iAvgBuf30[30]; unsigned long lTimeStart, lTimeEnd, lTiming; unsigned long lKeepStart, lKeepEnd; //int newLineReceived = 0;
//String inputString = ""; // a string to hold incoming data void setup()
{ Serial.begin(115200); Serial2.begin(115200); Serial3.begin(115200); pinMode(MIC, INPUT);
pinMode(LED, OUTPUT); // LED + pinMode(A2, OUTPUT); // LED - pinMode(BEEP, OUTPUT); // Beep pinMode(A4, OUTPUT); // Beep- pinMode(RELAY, OUTPUT);
pinMode(RELAYB, OUTPUT); analogWrite(A1, 0x00);
analogWrite(A2, 0x00); // LED - analogWrite(A4, 0x00); // Beep- digitalWrite(RELAY, HIGH); digitalWrite(RELAYB, HIGH); iStep = 0; // init data iLED = 0; // init data 0,Off 1,On iRelay = 0; // init data 0,Off 1,On iAvgIp = 0; // init data lTimeStart = 0; for (int i = 0; i < 30; i++) // init data { iAvgBuf30[i] = analogRead(MIC); } for (int i = 0; i < 2; i++)
{ tone(BEEP, 350); delay(100); noTone(BEEP); delay(100); } iEMax = 0; iEKeep = 0; } void loop()
{ int iTemp; //Serial2.println(analogRead(MIC));
Flash_dB(); SamplingIII(); if (iStep == 0)
{ //Serial.print("Val: "); //Serial.print(analogRead(MIC)); //Serial.print(" "); //Serial.print(fdB / 1.0f); //Serial.print(" "); if (fdB > fAvg) { iTemp = fdB - fAvg; } else { iTemp = fAvg - fdB; } //Serial.print(iTemp); Serial3.println(iTemp); if (iEMax > iTemp + 20)
{ if (iEKeep > 50) { iEKeep = 0; iEMax = iEMax-1; } iEKeep++; } else { iEKeep = 0; } if (iTemp > iEMax)
{ iEMax = iTemp; } //Serial.print(" "); //Serial.println(iEMax); //Serial2.println(iEMax); } } void SamplingIII()
{ int iTemp; // iStep = 11 if(iStep == 11) { iBlink = 0; lKeepStart = millis(); // init data lKeepEnd = millis(); // init data while ((lKeepEnd - lKeepStart) < KEEPTIME) { lKeepEnd = millis(); Flash_dB(); if (iDifference > iEMax+ TRIGGERMIN) { iEMax+= TRIGGERMIN; lKeepStart = millis(); // init data lKeepEnd = millis(); // init data Serial.print("11 : "); // for debug Serial.println(iDifference); // for debug Serial3.println(iDifference); // for debug } if ((iBlink > 100) && (iLED == 0)) { iBlink = 0; iLED = 1; // init data 0,Off 1,On analogWrite(LED, 0x80); } if ((iBlink > 100) && (iLED == 1)) { iBlink = 0; iLED = 0; // init data 0,Off 1,On analogWrite(LED, 0x00); } iBlink++; } analogWrite(LED, 0x00); iLED = 0; iStep = 0; lTimeStart = 0; } if ((iStep == 0) || (iStep == 2)) { Flash_dB(); if (iDifference > iEMax+ TRIGGERVAL) { if (iStep == 0) { lTimeStart = millis(); iStep = 1; Serial.println(" 1 : "); } else if (iStep == 2) { iStep = 3; // Step 3 Serial.println(" 3 : "); } iLoKeep = 0; } } if ((iStep == 1) || (iStep == 3)) // iStep On { Flash_dB(); if (iDifference < iEMax+ TRIGGERMIN) { iLoKeep++; if (iLoKeep > 50) { if (iStep == 1) { iStep = 2; // Step 2 Serial.println(" 2 : "); } else if (iStep == 3) { iStep = 4; // Step 4 Serial.println(" 4 : "); tone(BEEP, 10); delay(200); noTone(BEEP); delay(200); } } } } if (iStep == 4)
{ Serial.println(" 5 : "); lKeepStart = millis(); // init data lKeepEnd = millis(); // init data while ((lKeepEnd - lKeepStart) < KEEPTIME) { lKeepEnd = millis(); Flash_dB(); if (iDifference > iEMax+TRIGGERMIN) { iStep = 11; lTimeStart = 0; lKeepEnd = KEEPTIME + 1; Serial.println("Keep Error!\n"); // for debug } } if (iStep == 4) { for (int i = 0; i < 2; i++) { tone(BEEP, 10); delay(50); noTone(BEEP); delay(50); } iStep = 6; Serial.println(" 6 : "); lTimeStart = millis(); } } if ((iStep == 6) || (iStep == 8))
{ Flash_dB(); if (iDifference > iEMax+ TRIGGERVAL) { if (iStep == 6) { lTimeStart = millis(); iStep = 7; Serial.println(" 7 : "); tone(BEEP, 10); delay(200); noTone(BEEP); delay(200); } else if (iStep == 8) { iStep = 9; Serial.println(" 9 : "); } iLoKeep = 0; } } if ((iStep == 7) || (iStep == 9)) // { Flash_dB(); if (iStep == 7) { lKeepStart = millis(); lKeepEnd = millis(); Serial.println(" 8 : "); while ((lKeepEnd - lKeepStart) < KEEPTIME) { lKeepEnd = millis(); Flash_dB(); if (iDifference > iEMax+ TRIGGERMIN) { lKeepStart = millis(); lKeepEnd = millis(); Serial.print(" 8 : Error dB: "); Serial.println(iDifference); iStep = 11; lTimeStart = 0; break; } } if (iStep == 11) { // do notiing } else { iStep = 8; // Step 8 for (int i = 0; i < 3; i++) { tone(BEEP, 10); delay(50); noTone(BEEP); delay(50); } lTimeStart = millis(); } } else if (iStep == 9) { if (iStep == 9) { Serial.println("10 : "); lTimeEnd = millis(); if ((lTimeEnd - lTimeStart) < HITSEC) { if (iRelay == 0) { iRelay = 1; // init data 0,Off 1,On digitalWrite(RELAY, LOW); // Digi Sig digitalWrite(RELAYB, LOW); // Digi Sig } else { iRelay = 0; // init data 0,Off 1,On digitalWrite(RELAY, HIGH); // Digi Sig digitalWrite(RELAYB, HIGH); // Digi Sig } tone(BEEP, 10); delay(200); noTone(BEEP); delay(200); iStep = 11; lTimeStart = 0; } else { iStep = 11; lTimeStart = 0; } } } } if (lTimeStart != 0)
{ lTiming = millis(); if ((lTiming - lTimeStart) > TRIGGERSEC) { iStep = 11; lTimeStart = 0; Serial.println("Over Time!"); } } Serial.print("iStep: "); Serial.println(iStep); } void Flash_dB()
{ iSoundVal = analogRead(MIC); if (iAvgIp >= 30) { iAvgIp = 0; } iAvgBuf30[iAvgIp] = abs(iSoundVal); iAvgIp++; fAvg = 0; for (int i = 0; i < 30; i++) { fAvg = fAvg + iAvgBuf30[i]; } fAvg = fAvg / 30.0f; fdB = iSoundVal; if (fdB > fAvg) { iDifference = fdB - fAvg; } else { iDifference = fAvg - fdB; } } |
開啟Arduino IDE軟體.
設定裝置及COM位置,若不知道設定方式或使用方式,請參考我的另一篇文章"Arduino IDE"
http://thirtysec.pixnet.net/blog/post/222467340
建立一個新檔案,然後將原始碼完整的覆蓋在新檔案的內容,如下圖.
將程式碼上傳至裝置,即可測試.
測試影片
這段測試影片,是我原始碼寫到G3時就已錄製,所以跟介紹影片不太一樣,請多包涵.哈哈
操作方式跟介紹影片(G4版本)一樣,若你測試結果是一樣的,那你就成功一半了.
連接開關電路
這是最後的步驟,因為這步驟會用到電壓110V所以製作這個步驟請務必小心
電路圖如上.因為要做成成品.接下來連接的部分就請個位發揮巧思.裝到你想裝的地方啦.
我的想法是,想將這電路裝入延長線,這樣就可以把一般的延長線改裝成聲控的延長線了.
但...延長線買太小了,以至於塞不進去,所以只好外露大部分的元件-_-|||
再加上外殼跟元件的不合,所以我用了熱熔膠來固定元件.
最後.附上我的成品圖給各位參考.
28開關內部
28開關外觀1
文章標籤
全站熱搜
留言列表