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!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s