Usando dados do acelerômetro de um smartphone com o browser
Enquanto migrava meus nós de uma Rede de Sensores sem Fio baseada em 802.15.4 para “Internet of Things” baseado em 802.11, principalmente em aplicações voltadas a robótica e movimento, onde os dados do acelerometro eram requeridos, precisei constantemente usar o Android Studio ou o APPinventor do MIT, e isso é algo contraproducente. Procurando alternativas mais diretas, acabei conhecendo o evento ‘devicemotion’ do javascript, e isso tornou as coisas muito mais divertidas!
Saber se o evento é suportado(tentei em muitos devices e é em todos) é bem fácil:
if (window.DeviceMotionEvent) { document.getElementById("INFO").innerHTML = "Acelerometro suportado" } else { document.getElementById("INFO").innerHTML = "Acelerometro não suportado" }
E usá-lo é ainda mais fácil:
window.addEventListener('devicemotion', dmHandler, false);
O evento é hookado e chama uma função, dmHandler no caso, para tratá-lo. Uma exemplo de um handler seria:
function dmHandler(eventData) { acceleration = eventData.accelerationIncludingGravity; var left = 0; var right = 0; if (Math.abs(acceleration.y) > 1) { var speed = acceleration.y * 123; left = Math.min(1023, speed + acceleration.x * 100); right = Math.min(1023, speed - acceleration.x * 100); } else if (Math.abs(acceleration.x) > 1) { var speed = Math.min(1023, Math.abs(acceleration.x) * 123); if (acceleration.x > 0) { left = speed; right = -speed; } else { left = -speed; right = speed; } } var direcao = ""; direcao = "[" + Math.round(acceleration.x) + "," + Math.round(acceleration.y) + "," + Math.round(acceleration.z) + "]<BR/>" + Math.round(left) + ", " + Math.round(right); document.getElementById("MOSTRA").innerHTML = direcao; }
Depois disso, so chamar uma outra função para transferir os dados para o dispositivo:
var _ultimo = 0; function diz(_esquerda, _direita) { var now = Date.now(); if (_ultimo + 200 < now) { _ultimo = now; var _req = new XMLHttpRequest(); _req.open('GET', '/go/' + Math.round(_esquerda) + "," + Math.round(_direita), true); _req.send(null); } }
E colocando tudo junto:
<!DOCTYPE HTML> <html><head> </head><body> <div id="INFO"></div> <br/> <div id="MOSTRA"></div> <br/> <script type='text/javascript'> if (window.DeviceMotionEvent) { window.addEventListener('devicemotion', dmHandler, false); document.getElementById("INFO").innerHTML = "Acelerometro suportado" } else { document.getElementById("INFO").innerHTML = "Acelerometro nao suportado" } var _ultimo = 0; function diz(_esquerda, _direita) { var now = Date.now(); if (_ultimo + 200 < now) { _ultimo = now; var _req = new XMLHttpRequest(); _req.open('GET', '/go/' + Math.round(_esquerda) + "," + Math.round(_direita), true); _req.send(null); } } function dmHandler(eventData) { acceleration = eventData.accelerationIncludingGravity; var left = 0; var right = 0; if (Math.abs(acceleration.y) > 1) { var speed = acceleration.y * 123; left = Math.min(1023, speed + acceleration.x * 100); right = Math.min(1023, speed - acceleration.x * 100); } else if (Math.abs(acceleration.x) > 1) { var speed = Math.min(1023, Math.abs(acceleration.x) * 123); if (acceleration.x > 0) { left = speed; right = -speed; } else { left = -speed; right = speed; } } var direcao = ""; direcao = "[" + Math.round(acceleration.x) + "," + Math.round(acceleration.y) + "," + Math.round(acceleration.z) + "]<BR/>" + Math.round(left) + ", " + Math.round(right); document.getElementById("MOSTRA").innerHTML = direcao; } </script> </body></html>
E no meu embarcado, estou usando o bottle( https://paoloo.wordpress.com/2015/11/19/bottle-py-a-solucao-de-um-problema-que-nao-deveria-existir/ ) para gerenciar:
# -*- coding: utf-8 -*- from bottle import request, route, run, static_file @route('/') def get_BASEdata(): return static_file("loader.html", root="./") @route('/go/<d>') def get_SENTdata(d): print d # ou faz algo mais util, como enviar os valores para o controlador dos motores return d run(host='0.0.0.0', port=8080, debug=True)
E é isso. Simples, direto e não requer nada além de um browser!