iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 8
0
Modern Web

Webduino 不只是物聯網,智慧插座也可以很 Modern~系列 第 8

實戰智慧插座 08 - 你拍拍手我就開燈 ( 聲音偵測 )

在「距離偵測」和「人體紅外線偵測」之後,這篇要來介紹「聲音偵測」( 不是語音辨識,比較貼切的應該是指「有沒有聲音」,語音辨識在之後會介紹 )。



聲音偵測傳感器

這裏我使用的是簡單的聲音偵測傳感器,並不是分貝計無法偵測大小聲,只能透過傳感器本身靈敏度的調整,靈敏度可以透過傳感器上頭的十字旋鈕更改,偵測有沒有聲音的原理主要根據「震動」,當偵測到「有」聲音的時候,會發送「高電位」訊號。
Webduino 偵測聲音開燈

接線的方式只要把 5V 接在 5V 的位置,GND 接 GND,OUT 接訊號腳就可以。
Webduino 偵測聲音開燈

接線完成後,先透過 Webduino Blockly ( https://blockly.webduino.io ) 來測試一下,首先打開內嵌的網頁,選擇「顯示文字」,放入開發板的積木,輸入裝置的 device ID,接著放入聲音偵測傳感器的積木,腳位設定為 10 號腳,設定「有偵測到」和「沒有偵測到」的對應事件。( 其實和人體紅外線偵測幾乎一模一樣 )
Webduino 偵測聲音開燈

點選右上角的執行,在聲音傳感器周圍拍拍手,就會出現「你是在大聲什麼啦」的文字,如果不發出聲音,就會出現「偵測中...」的字樣。
Webduino 偵測聲音開燈

如果近一點看傳感器,可以看到偵測到聲音的時候,上面有個小紅燈會亮起。
Webduino 偵測聲音開燈



Webduino 程式用法

知道怎麼接收聲音傳感器的訊號並做動作之後,再來就是要控制智慧插座上的電燈了,如果 GND 只有一個,就必須要用麵包板外接,接線圖如下:
Webduino 偵測聲音開燈

和人體紅外線偵測的做法幾乎一模一樣,一開始先在自己的網頁內引入「 webduino-min.js 」還有「 webduino-blockly.js 」這兩個 JavaScript,這樣我們才有操控開發板以及聲音偵測的 API 可以使用,在 body 的區域放入一個 h2 來顯示一些文字訊息,然後放入兩張燈泡一明一暗的圖片,讓偵測到訊號的時候,網頁上的燈泡也會發生反應。

<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
  <title>Webduino</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
  <script src="https://webduino.io/components/webduino-js/dist/webduino-all.min.js"></script>
  <script src="https://blockly.webduino.io/webduino-blockly.js"></script>
</head>

<body>
  <h2 id="show"></h2>
  <img src="http://example.oxxostudio.tw/it2016/it2016-day05-on.jpg" id="on">
  <img src="http://example.oxxostudio.tw/it2016/it2016-day05-off.jpg" class="show" id="off">
</body>
</html>

再來就看看聲音偵測的使用方法,聲音偵測的宣告使用 getSound(board, pin),pin 是數位腳,例如接在 10 號腳就改為 10。

sound = getSound(board, 10);

偵測的方式使用 .on(event, callback),event 有兩種,一種是 detected 也就是偵測到訊號,另外一種是 ended,有別於人體紅外線會有「延遲」,聲音偵測的傳感器是沒有延遲的,所以如果需要延遲,就必須要自己在網頁裡面完成

sound.on("detected", function(){
  //偵測到聲音的時候要做什麼事
});
sound.on("ended", function(){
  //結束後會做什麼事
});


網頁控制

了解用法之後,可以按照下面的寫法,在偵測到有聲音就把顯示文字改為「你是在大聲什麼啦!」同時把實際的燈泡以及網頁的燈泡點亮,然後「經過一秒」( 這邊必須要寫在網頁裡 ),沒有偵測到人,就在把訊息換成「偵測中...」,同時把網頁燈泡和實際燈泡關起來。

HTML 的部分就不介紹了,就跟上面寫得一模一樣 ( 滑鼠往上拉 ),CSS 的部分也很陽春,就只是寫個簡單的控制燈泡圖片有沒有出現而已。

img{
  display:none;
}
.show{
  display:block;
}

JavaScript 的說明就直接寫在程式碼裡頭,最主要就是多設定一個變數初始值是 0,在每一次偵測到訊號的時候都會「加 1」,這樣就可以判斷是否為「一秒內」的「第一次」所偵測到的訊號 ( 因為如果連續偵測,這個變數的數值就不會是 1 ),接著透過 setTimeout 來延遲,再延遲之後再把這個變數設為 0 就可以了。

$(function(){
  var sound,
      led,
      $show=$('#show'),
      $on = $('#on'), 
      $off = $('#off'); 

  var a = 0; //設一個變數,判斷是不是在一秒內偵測的訊號

  boardReady('你的裝置 ID', function (board) {
    board.systemReset();
    board.samplingInterval = 250;
    sound = getSound(board, 11);  //設定聲音偵測傳感器為 11 號腳
    led = getLed(board, 10); //設定 LED 為 10 號腳
    $show.text('偵測中...');
    sound.on("detected", function(){
      a = a + 1;
      if(a === 1){
        light_On(); // 一秒內的第一次偵測,就執行點燈的流程
        setTimeout(function(){
          a = 0;  //過一秒之後就把 a 變回 0
          light_Off();   //同時把燈熄滅
        }, 1000);
      }
    });
    sound.on("ended", function(){
      if(a === 0){
       light_Off();
      }
    });

    //這是點燈的流程
    function light_On(){
      $show.text('你是在大聲什麼啦!');
      led.on();
      $on.addClass('show');
      $off.removeClass('show');
    }
    ////這是熄燈的流程
    function light_Off(){
      $show.text('偵測中...');
      led.off();
      $on.removeClass('show');
      $off.addClass('show');
    }
  });

});

最終結果 ( 範例:http://bin.webduino.io/jerip/1/edit?html,css,js,output )
因為是 Gif 動畫聽不到啪啪啪的聲音,不過應該看得出來是拍手啦!
Webduino 偵測聲音開燈



小結

每次只要用到聲音傳感器,都會想到金凱瑞演的「王牌天神」還有班。史提勒的「博物館驚魂夜」,裡面都有一個橋段用彈指開燈或是拍手開燈,其實透過聲音傳感器就能夠做到一樣的效果了喔。

參考資料


上一篇
實戰智慧插座 07 - 你是「人」我就開燈 ( 人體紅外線偵測 )
下一篇
實戰智慧插座 09 - 用電視機遙控器開燈 ( 紅外線發射器 )
系列文
Webduino 不只是物聯網,智慧插座也可以很 Modern~30

尚未有邦友留言

立即登入留言