Kadence

手機陀螺儀

玩過人臉追蹤與顏色追蹤之後,接著把焦點拉回手機上,既然我們可以透過網頁做這麼多事情,若是用手機或平板打開網頁,能否發揮行動裝置的優勢呢?這篇文章將會介紹如何透過網頁獲取行動裝置陀螺儀的數值 ( 前後左右翻轉 ),然後把這些數值拿來控制智慧插座的電燈泡。

相關 Webduino 教學參考:自走車 ( 行動裝置操控 )

獲取陀螺儀數值

要使用行動裝置的陀螺儀,只要監聽 deviceorientation 的事件就可以,它的用法和 click 是一模一樣的。

window.addEventListener('deviceorientation', function(event) {
  var alpha = event.alpha;
  var beta = event.beta;
  var gamma = event.gamma;
}, false);

從上述最基本的程式碼中可以看到,這個事件有三個 API,分別是:alphabeta 以及 gamma,這三個 API 代表甚麼意思呢?下面三張圖分別表現三個軸轉動的角度和方向。

  • alpha
    行動裝置水平放置時,繞 Z 軸旋轉的角度,數值為 0 度到 360 度。

alpha 行動裝置示意圖

  • beta
    行動裝置水平放置時,繞 X 軸旋轉的角度,數值為 -180 度到 180 度。

beta 行動裝置示意圖

  • gamma
    行動裝置水平放置時,繞 Z 軸旋轉的角度,數值為 -90 度到 90 度。

gamma 行動裝置示意圖

接著就用簡單的範例來測試看看,下面的範例在畫面中放入三個區塊,分別代表 alpha、beta 與 gamma,當用手機打開這個網頁,轉動手機就會看到數值的變化。此外在一開始也加入一個判斷式,如果手機不支援,則會顯示不支援的文字訊息,判斷的方式為讀取 window 是否有 DeviceOrientationEvent 這個屬性,其實也可以從瀏覽器的 console 裏頭看到 window 是否有包含這個屬性。

HTML 就擺上三個區塊:

alpha:<span id="alpha"></span><br/>
beta:<span id="beta"></span><br/>
gamma:<span id="gamma"></span><br/>

Javascript 的部分利用 window.addEventListener 監聽 deviceorientation 事件,接著就可以獲取 alpha、beta 和 gamma,不過獲取到的數值其實是個有非常多個小數點位數的數值,再利用 Math.round 來四捨五入。

if(window.DeviceOrientationEvent) {
  window.addEventListener('deviceorientation', function(event) {
  var a = document.getElementById('alpha'),
        b = document.getElementById('beta'),
        g = document.getElementById('gamma'),
        alpha = event.alpha,
        beta = event.beta,
        gamma = event.gamma;

  a.innerHTML = Math.round(alpha);
  b.innerHTML = Math.round(beta);
  g.innerHTML = Math.round(gamma);

    }, false);
}else{
    document.querySelector('body').innerHTML = '你的瀏覽器不支援喔';
}

完成後,用手機打開旋轉一下,應該就可以看到數值的變化了。

旋轉手機顯示陀螺儀偵測數值

獲取加速度計數值

除了可以偵測旋轉與翻轉之外,現在也可以透過 devicemotion,從行動裝置的加速度計獲得三個維度的加速度。

window.addEventListener('devicemotion', function(event) {
  var x = event.acceleration.x;
  var y = event.acceleration.y;
  var z = event.acceleration.z;
}, false);

實際上 devicemotion 還可以做得更多

// 加速感測包括重力參數
event.accelerationIncludingGravity.x
event.accelerationIncludingGravity.y
event.accelerationIncludingGravity.z

// 旋轉率
event.rotationRate.alpha
event.rotationRate.beta
event.rotationRate.gamma

實際做個網頁測試一下,這邊有利用 Math.round 來四捨五入。

if(window.DeviceOrientationEvent) {
  window.addEventListener('devicemotion', function(event) {
  var tx = document.getElementById('tx’)',
        ty = document.getElementById('ty'),
          tz = document.getElementById('tz'),
          x = event.acceleration.x,
          y = event.acceleration.y
          z = event.acceleration.z;

    tx.innerHTML = Math.round(x);
    ty.innerHTML = Math.round(y);
    tz.innerHTML = Math.round(z);

    }, false);
}else{
    document.querySelector('body').innerHTML = '你的瀏覽器不支援喔';
}

完成後,把手機上下左右移動,就可以看到加速度變化。

手機上下左右移動顯示加速速偵測素質

左右翻轉點亮燈泡

知道原理之後就來控制實際的插座,首先測試「左右翻轉」,往左翻就開燈,往右翻就關燈,網頁上就只顯示數值就可以,HTML 先引入對應的 JavaScript,放入一個 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>
</body>
</html>

再來看到 JavaScript,把剛剛上面介紹過的程式碼複製下來用,記得要寫入裝置的程式碼,然後我這邊是讓 gamma 數值大於零 ( 也就是往右翻 ) 的時候會開燈。( 其實你也可以放 12 個燈泡圍成一個圈,透過 alpha 的數值,就可以轉到哪個燈泡,哪個燈泡就亮起來 )

$(function(){

  var led, alpha, beta, gamma;
      $show=$('#show');

  //裝置連線
  boardReady('你的裝置 ID', function(board) {
    $show.html('準備中...');
    board.systemReset();
    board.samplingInterval = 250;
    board.autoReconnect = true;
    led = getLed(board, 10); //設定 LED 為 10 號腳

    if(window.DeviceOrientationEvent) {
      window.addEventListener('deviceorientation', function(event) {
        var alpha = Math.round(event.alpha),
            beta = Math.round(event.beta),
            gamma = Math.round(event.gamma);

        $show.html(gamma); //左右翻轉使用 gamma
        if(gamma>0){
          led.on();
        }else{
          led.off();
        }

      }, false);
    }else{
        $show.html('瀏覽器不支援');
    }
  });

});

最後的結果如下,當我們翻轉手機,燈泡就會亮起。

翻轉手機啟動智慧插座燈泡開關

搖動手機點亮燈泡

除了翻轉手機,也可以透過加速度來開燈,這邊實作一個搖一搖手機就開燈的效果,因為手機可能隨時都在動,就算我們認為是上下晃,左右晃的程度也要考慮進去,所以這裡最主要這邊有設定一個搖動的臨界值 shak_threshold,然後透過時間差的換算,就可以在我們想要的晃動幅度,進行我們指定的流程。

$(function(){

  var $show=$('#show'),
      led,x,y,z,
      a = 0,
      shak_threshold = 2000,
      last_update = 0,
      last_x = 0,
      last_y = 0,
      last_z = 0;

  //裝置連線
  boardReady('你的裝置 ID', function (board) {
    $show.html('準備中...');
    board.systemReset();
    board.samplingInterval = 250;
    board.autoReconnect = true;
    led = getLed(board, 10); //設定 LED 為 10 號腳

    if(window.DeviceMotionEvent) {
      window.addEventListener('devicemotion', function(event) {

        var acceleration = event.accelerationIncludingGravity;
        var curTime = new Date().getTime(); //獲取當前時間
        if((curTime - last_update) > 100){
    //設定間隔時間,避免短時間的內的晃動干擾
            var diffTime = curTime - last_update;
            last_update = curTime;
            x = Math.round(acceleration.x);
            y = Math.round(acceleration.y);
            z = Math.round(acceleration.z);
    //計算晃動速度
            var speed = Math.abs((x + y + z - last_x - last_y - last_z)) / diffTime * 10000;
            $show.html(speed);
            if(speed > shak_threshold && a<1){
              a = 1;
              led.on();
              setTimeout(function(){
                led.off();
                a = 0;
              },1000);
            }
        }

      }, false);
    }else{
        $show.html('瀏覽器不支援');
    }
  });

});

最後的結果如下,當我們搖動手機到一定程度,燈泡就會亮起。

搖動手機啟動智慧插座燈泡開關

小結

如果不太會寫程式,其實 Webduino Blockly 編輯工具 ( https://blockly.webduino.io ) 也提供了手機陀螺儀與加速度計的功能,有興趣也可以使用看看,打開下面的範例網頁,點選右上角的 QRCode 用手機掃描就可以囉!

手機陀螺儀:https://goo.gl/3rzqJo

Webduino Blockly 手機陀螺儀積木

手機加速度計:https://goo.gl/PB1BcT

Webduino Blockly 手機加速度積木

參考資訊:HTML5 控制裝置陀螺儀 ( 三軸 )

分享