milkcocoaのチュートリアルを参考に、スマホの傾き(画面状況)でラズパイに繋いだサーボモータを制御してみました。
Qiita初投稿のため、見づらかったり、変な所があるかもしれませんが、その点はご指摘頂けたら幸いです。
##今回使用したもの
・Raspberry Pi2 Model B
・サーボモータ EK2-0500
・Node.js
・Heroku
・Milkcocoa
ラズパイ周りの配線はこんな感じ。サーボの電源はラズパイのvddから取ることにします(複数使う場合は外部電源を用意して下さい)。
サーボの信号線はGPIO18のピンを使っています。今回はServoBlasterを用いてサーボ制御を行います。
##スマホ側
HerokuにNode.jsで書いたWebアプリをデプロイしました。今回はexpress(テンプレートエンジンはejs)で雛形を作って、そこにmilkcocoaのチュートリアルで使われていたコードをそのまま使いました(もちろんuer_idのみ自分の物に変更)。
ここではherokuへのデプロイ、expressの導入・説明は省略します。
<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>
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のモジュール読み込ませます。
//モジュール読み込みの行の最後に追加
var MilkCocoa = require('milkcocoa');
デプロイしてサイトにアクセスすると、スマホのX軸とY軸の傾きの値が左上に出てくると思います。
この値を元にスマホが縦か横の状態判断を行い、データストアにある"inclination"の値が変化します。
##ラズパイ側
まず適当に作ったプロジェクトフォルダにモジュールを用意します。
npm init
npm install milkcocoa
npm install servoblaster
そうしたら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