玩過人臉追蹤與顏色追蹤之後,接著把焦點拉回手機上,既然我們可以透過網頁做這麼多事情,如果用手機或平板打開網頁,能否發揮行動裝置的優勢呢?這篇文章將會介紹如何透過網頁獲取行動裝置陀螺儀的數值 ( 前後左右翻轉 ),然後把這些數值拿來控制智慧插座的電燈泡。
講到行動裝置陀螺儀就要參考我之前寫的文章:OXXO.STUDIO ~ HTML5 控制裝置陀螺儀 ( 三軸 ),要使用行動裝置的陀螺儀,我們只要監聽 deviceorientation
的事件就可以,它的用法和 click
是一模一樣。
window.addEventListener('deviceorientation', function(event) {
var alpha = event.alpha;
var beta = event.beta;
var gamma = event.gamma;
}, false);
從上述最基本的程式碼中可以看到,這個事件有三個 API,分別是:alpha、beta 以及 gamma,這三個 API 代表甚麼意思呢?下面三張圖分別表現三個軸轉動的角度和方向。
aplha
行動裝置水平放置時,繞 Z 軸旋轉的角度,數值為 0 度到 360 度。
beta
行動裝置水平放置時,繞 X 軸旋轉的角度,數值為 -180 度到 180 度。
gamma
行動裝置水平放置時,繞 Z 軸旋轉的角度,數值為 -90 度到 90 度。
接著就用簡單的範例來測試看看,下面的範例我在畫面中放入三個區塊,分別代表 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 = '你的瀏覽器不支援喔';
}
完成後,用手機打開旋轉一下,應該就可以看到數值的變化了。
( 程式:http://bin.webduino.io/ribuq/4/edit?html,css,js,output )
除了可以偵測旋轉與翻轉之外,現在也可以透過 devicemotion
,從行動裝置的加速度計獲得三個維度的加速度。
window.addEventListener('devicemotion', function(evnet) {
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 = '你的瀏覽器不支援喔';
}
完成後,把手機上下左右移動,就可以看到加速度變化。
( 程式:http://bin.webduino.io/xiqiy/1/edit?html,css,js,output )
知道原理之後我們就來控制實際的插座,首先我們先來測試「左右翻轉」,往左翻就開燈,往右翻就關燈,網頁上就只顯示數值就可以,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 個燈泡圍成一個圈,透過 aplha 的數值,就可以轉到哪個燈泡,哪個燈泡就亮起來 )
$(function(){
var led, aplha, 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('瀏覽器不支援');
}
});
});
最後的結果如下,當我們翻轉手機,燈泡就會亮起。
( 程式:http://bin.webduino.io/coqez/1/edit?html,js,output )
除了翻轉手機,也可以透過加速度來開燈,這邊我實作一個搖一搖手機就開燈的效果,因為手機可能隨時都在動,就算我們認為是上下晃,左右晃的程度也要考慮進去,所以這裡最主要這邊有設定一個搖動的臨界值 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('瀏覽器不支援');
}
});
});
最後的結果如下,當我們搖動手機到一定程度,燈泡就會亮起。
( 程式:http://bin.webduino.io/rahiq/1/edit?html,js,output )
如果不太會寫程式,其實 Webduino Blockly 編輯工具 ( https://blockly.webduino.io ) 也提供了手機陀螺儀與加速度計的功能,有興趣也可以使用看看,打開下面的範例網頁,點選右上角的 QRCode 用手機掃描就可以囉!
手機陀螺儀 ( http://blockly.webduino.io/#-K_Dv_47bY4xaMvf65pk )
手機加速度計 ( http://blockly.webduino.io/#-K_DvO27DPYUwAt6rUi8 )
參考資訊: