前回,スマホを最高級電子部品として電子工作に組み込むで,OpenCVを使ってサーボモータを動かすのを書きました.
好評だったので,今度はスマホの加速度を使ってみたいと思います.
加速度モジュールではなくスマホで加速度を取る利点
- キャリブレーションがいらない
 - 無線なので,電子回路から離れた場所の加速度を取ることができる
 - 精度が段違い
 - サンプリング数も段違い
 
どうやってスマホの加速度を使うか については,前回と同じくobnizを使って,HTML経由で加速度を取ります.
詳細はこちらの公式サイトを見てください
obniz.io
作ったもの
せっかくなので,上記の利点を最大限活用できるものがいいですよね.
リモートで加速度を使うもの・・・そうだ,ラジコンにしよう! 
というわけで,iPhoneの加速度をインプットにしたラジコンを作りました.
これを作るのに書いたコードがたったの1時間/60行程度で作れちゃいました
(OpenCVよりよっぽど簡単でした)
材料
作り方
ハードウェア
回路は回路図がいらないぐらい,ただただシンプルにモータとobnizをつなげるだけです
本体は簡単にダンボール工作で作りました.
ハサミで切れ目を入れて挟むだけの簡単工作です


obnizがだらんとしているのが嫌だったので,obnizを挟む切れ目も入れて挟んでいます
モバイルバッテリーはお好きなところにおいてください
ソフトウェア
まずいちばん大事な,加速度を取るところですが,たった3行でできます.
カメラのときとは段違いですね
window.addEventListener("devicemotion", function (event1) {
    let x = event1.accelerationIncludingGravity.x;
}
これで加速度が変化したときに,関数が呼ばれて加速度の値を取得できます.
それに応じてモーターを動かすのがこちら
motorL = obniz.wired("DCMotor", {forward: 0, back: 1});
motorL.power(100)
motorL.move(true);
obnizのどのピンにモーターがつながっているか設定して,あとはpowerとmove関数で,速度と方向を指定したら動きます.
あとは,X軸Y軸の加速度に応じてパワーと方向を変えるだけです.
今回はiPhoneを前後に傾けると前進・後退,左右に傾けたら回転をするようにしました.
HTML全体はこうなります
<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
  <script src="https://unpkg.com/obniz@1.3.0/obniz.js" crossorigin="anonymous"></script>
</head>
<body>
<div id="obniz-debug"></div>
<h1>obniz robot controller </h1>
<div id="print"></div>
<script>
  let obniz = new Obniz("2580-0064");
  let motorL, motorR;
  let threshold = 1, maxAccel = 5;
  obniz.onconnect = function () {
    motorL = obniz.wired("DCMotor", {forward: 0, back: 1});
    motorR = obniz.wired("DCMotor", {forward: 10, back: 11});
  };
  window.addEventListener("devicemotion", function (event1) {
    let x = event1.accelerationIncludingGravity.x;
    let y = event1.accelerationIncludingGravity.y;
    if (!motorR || !motorL) {
      return;
    }
    if (Math.abs(y) > threshold) {
      let power = Math.min(100 * (Math.abs(y) - threshold) / (maxAccel - threshold), 100);
      motorL.power(power);
      motorR.power(power);
      let direction = y > 0;
      motorL.move(direction);
      motorR.move(direction);
    } else if (Math.abs(x) > threshold) {
      let power = Math.min(100 * (Math.abs(x) - threshold) / (maxAccel - threshold), 100);
      if (x > 0) {
        motorR.power(power);
        motorR.move(true);
        motorL.stop();
      } else {
        motorL.power(power);
        motorL.move(true);
        motorR.stop();
      }
    } else {
      motorL.stop();
      motorR.stop();
    }
  }, true);
</script>
</body>
</html>
完成!
OpenCVよりもだいぶ簡単に作ることができました
前回の顔検出と合わせたら,人を追っかけるロボットなんてのも簡単に作れそうです.
音声認識もjsでできるので,「いけ!」って声をかけたら前進とかも作れそうですね!

