LoginSignup
8
8

More than 5 years have passed since last update.

ラズパイ+Milkcocoaでスマホの傾きでサーボ制御

Last updated at Posted at 2016-09-29

milkcocoaのチュートリアルを参考に、スマホの傾き(画面状況)でラズパイに繋いだサーボモータを制御してみました。
Qiita初投稿のため、見づらかったり、変な所があるかもしれませんが、その点はご指摘頂けたら幸いです。

今回使用したもの

・Raspberry Pi2 Model B
・サーボモータ EK2-0500
・Node.js
・Heroku
・Milkcocoa

ラズパイ周りの配線はこんな感じ。サーボの電源はラズパイのvddから取ることにします(複数使う場合は外部電源を用意して下さい)。
zu1.png
サーボの信号線はGPIO18のピンを使っています。今回はServoBlasterを用いてサーボ制御を行います。

スマホ側

HerokuにNode.jsで書いたWebアプリをデプロイしました。今回はexpress(テンプレートエンジンはejs)で雛形を作って、そこにmilkcocoaのチュートリアルで使われていたコードをそのまま使いました(もちろんuer_idのみ自分の物に変更)。
ここではherokuへのデプロイ、expressの導入・説明は省略します。

index.ejs
<body>
<div id="output"></div>
<script src='https://cdn.mlkcca.com/v0.6.0/milkcocoa.js'></script>
<script src="javascripts/main-sp.js"></script>
</body>
main-sp.js
window.onload = function(){

  var currentMode = 'portrait';
  var output = document.getElementById('output');

  // app_idは自分のものに書き換えてください
  var milkcocoa = new MilkCocoa('app_id');
  var ds = milkcocoa.dataStore('inclination');

  window.addEventListener('devicemotion', function(e){
    gravity = e.accelerationIncludingGravity;

    output.innerHTML
    = 'x方向: '+gravity.x
    + '<br>y方向: '+gravity.y;

    sendModeFromGravityValue(gravity);

  },true);


  function sendModeFromGravityValue(g){

    // 絶対値を取得
    var x = Math.sqrt(g.x * g.x);
    var y = Math.sqrt(g.y * g.y);

    // portrait -> landscape
    if(currentMode === 'portrait' && x > 8.5 && y < 1.5){
      currentMode = 'landscape';
      ds.send({mode: currentMode});
    }

    // landscape -> portrait
    if(currentMode === 'landscape' && x < 1.5 && y > 8.5){
      currentMode = 'portrait';
      ds.send({mode: currentMode});
    }
  }
};

あとapp.jsにmilkcocoaのモジュール読み込ませます。

app.js
//モジュール読み込みの行の最後に追加
var MilkCocoa = require('milkcocoa');

デプロイしてサイトにアクセスすると、スマホのX軸とY軸の傾きの値が左上に出てくると思います。
この値を元にスマホが縦か横の状態判断を行い、データストアにある"inclination"の値が変化します。

ラズパイ側

まず適当に作ったプロジェクトフォルダにモジュールを用意します。
npm init
npm install milkcocoa
npm install servoblaster
そうしたらservo.jsとして実行プラグラムを書きます。

servo.js
var MilkCocoa = require('milkcocoa');
var servoblaster = require('servoblaster');

//サーボ番号2(GPIO18)のサーボモータを使用を宣言
var stream = servoblaster.createWriteStream(2);

//use_idは自分の物に書き換えて下さい
var milkcocoa = new MilkCocoa('use_is');
var ds = milkcocoa.dataStore('inclination');

ds.on("send", chengeInclination);

function chengeInclination(sent){
    if(sent.value.mode === 'portrait'){
      //サーボの角度を130に設定(中心150。この場合は左回転)
      //なおこの値はサーボモータによって異なると思われます。
      stream.write(130);
    }
    if(sent.value.mode === 'landscape'){
      //サーボの角度を200に設定(右回転)
      stream.write(200); 
    }
}

ServoBlasterのサーボ番号とピンの関係は以下のようになっています。
(サーボ番号の3番についてはRaspberry PiのリビジョンによってGPIOの21か27になるそうです。)

サーボ番号 GPIO番号
0 4
1 17
2 18
3 21/27
4 22
5 23
6 24
7 25

node servo.jsで起動。
スマホでデプロイしたアプリにアクセスして、 スマホの画面を横にしたり縦にするとサーボが動きます。

今後はスマホの角度とサーボの角度を同期させて何か作ってみたいと思っています。

参考になった記事etc.

・ServoBlaster関連
 http://oohito.com/nqthm/archives/2151
 https://www.npmjs.com/package/servoblaster
・milkcocoa関連
 https://mlkcca.com/tutorial/page1.html

8
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8