先日の記事で、NodeJSでBLE通信ができるnobleライブラリでkonashiとつなげたメモです。
今回やりたいこと
今回やりたいことは以下のとおりです。
- Raspberry PiでBlueTooth関連のライブラリが入っていてBlueToothが使える状態が前提で進める。
- NodeJSでnobleライブラリを使って、konashiにアクセス。
- 1秒毎にLED ON/OFFしつつ、アナログ入力を計測する動きにする。
NodeJSでnobleライブラリを使う
早速使っていきます。Raspberry PiでBlueTooth関連のライブラリが入っていてBlueToothが使える状態が前提です。
NodeJSでは特に込み入ったことはなく、
npm install noble
でインストールします。
konashiを操作するためのUUID
konashiを操作するためのUUIDは本家のサイトを参考にします。
NodeJSに変数として保持しておきます。
var noble = require('noble'); // KONASHI自体のサービスID var KONASHI_SERVICE_UUID = '229bff0003fb40da98a7b0def65c2d4b'; // 操作したいpinのID var KONASHI_ANALOG_INPUT_PINID = '229b300803fb40da98a7b0def65c2d4b'; var KONASHI_PIO_SETTING_PINID = '229b300003fb40da98a7b0def65c2d4b'; var KONASHI_PIO_OUTPUT_PINID = '229b300203fb40da98a7b0def65c2d4b';
実際のコード
実際のコードは以下のとおりです。
オリジナルlittleBits Bluetooth(konashi)モジュールは、アナログ入力ピン AIO0、デジタル出力ピン PIO2で入出力をやり取りしています。
※このpinルールは開発中のものなので変更される可能性があります。そのときは読み替えましょう。
var noble = require('noble'); // KONASHI自体のサービスID var KONASHI_SERVICE_UUID = '229bff0003fb40da98a7b0def65c2d4b'; // 操作したいpinのID var KONASHI_ANALOG_INPUT_PINID = '229b300803fb40da98a7b0def65c2d4b'; var KONASHI_PIO_SETTING_PINID = '229b300003fb40da98a7b0def65c2d4b'; var KONASHI_PIO_OUTPUT_PINID = '229b300203fb40da98a7b0def65c2d4b'; // 各CHARACTERISTICSをUUIDから判断してcharacteristic格納する変数 var KONASHI_CHARACTERISTICS_ANALOG_READ; var KONASHI_CHARACTERISTICS_PIO_SETTINGS; var KONASHI_CHARACTERISTICS_PIO_OUTPUT; // LED ON/OFF var led_toggle = false; // 状態がパワーONだったらスキャンに移行 noble.on('stateChange', function(state) { console.log('on -> stateChange: ' + state); if (state === 'poweredOn') { noble.startScanning(); } else { noble.stopScanning(); } }); noble.on('scanStart', function() { console.log('on -> scanStart'); }); noble.on('scanStop', function() { console.log('on -> scanStop'); }); // discover 機器が発見されたら noble.on('discover', function(peripheral) { console.log('on -> discover: ' + peripheral); // まずスキャンをとめる noble.stopScanning(); // KONASHI接続時のイベント peripheral.on('connect', function() { console.log('on -> connect'); this.discoverServices(); }); // KONASHI切断時のイベント peripheral.on('disconnect', function() { console.log('on -> disconnect'); }); // 見つけたサービス(機器)へのアクセス peripheral.on('servicesDiscover', function(services) { for(i = 0; i < services.length; i++) { // サービスがKONASHI_SERVICE_UUIDと一致した時だけ処理 if(services[i]['uuid'] == KONASHI_SERVICE_UUID){ // サービスのcharacteristic捜索 services[i].on('includedServicesDiscover', function(includedServiceUuids) { console.log('on -> service included services discovered [' + includedServiceUuids + ']'); this.discoverCharacteristics(); }); // characteristic取得イベント services[i].on('characteristicsDiscover', function(characteristics) { // characteristics配列から必要なCHARACTERISTICSをUUIDから判断してcharacteristic格納 for(j = 0; j < characteristics.length; j++) { // アナログ入力 characteristic if( KONASHI_ANALOG_INPUT_PINID == characteristics[j].uuid ){ console.log("KONASHI_CHARACTERISTICS_ANALOG_READ exist!!"); KONASHI_CHARACTERISTICS_ANALOG_READ = characteristics[j]; } // PIO設定 characteristic // デジタル入出力を担当するPIO全部に出力するようにお願いする if( KONASHI_PIO_SETTING_PINID == characteristics[j].uuid ){ console.log("KONASHI_PIO_SETTING_PINID exist!!"); KONASHI_CHARACTERISTICS_PIO_SETTINGS = characteristics[j]; // PIOを全部出力に空けとく 11111111(255) ex) 11111110(254) KONASHI_CHARACTERISTICS_PIO_SETTINGS.write(new Buffer([255]), true); } // デジタル出力 characteristic if( KONASHI_PIO_OUTPUT_PINID == characteristics[j].uuid ){ console.log("KONASHI_PIO_OUTPUT_PINID exist!!"); KONASHI_CHARACTERISTICS_PIO_OUTPUT = characteristics[j]; } } // 実際の点滅させるところ setInterval(function(){ // ANALOG_READ /* 入力を監視 0~1.3でくる(0V~1.3Vという意味) ・ボタンモジュールを押す場合 ON = 0.000 / OFF = 1.3 みたいにくる 1.0あたりをしきい値にするといい ・DIMMERつまみモジュールの場合 ツマミひねると、0~0.23~0.56~0.89~1.12~1.3 みたいにくる */ KONASHI_CHARACTERISTICS_ANALOG_READ.read(function(error, data) { if (data) { console.log( 'value:' + (data[1] + data[0]*256)/1000 ); } }); // 実際の点滅 // DEGITAL OUTPUT PIO2 if(led_toggle){ // LED ON console.log("LED ON"); KONASHI_CHARACTERISTICS_PIO_OUTPUT.write(new Buffer([255]), true); } else { // LED OFF console.log("LED OFF"); KONASHI_CHARACTERISTICS_PIO_OUTPUT.write(new Buffer([0]), true); } // LED ON/OFFの反転 led_toggle = !led_toggle; }, 1000); }); services[i].discoverIncludedServices(); } } }); // 機器との接続開始 peripheral.connect(); });
こちらで、アナログ入力が計測でき、デジタル出力でLEDなどOUTPUTモジュールをくっつけると繰り返しON/OFFされます。
Raspberry Piで起動した時の様子です。
1秒毎にLED ON/OFFしつつ、アナログ入力を計測してますね。
アナログ入力についてはスライドレバー(SLIDE DIMMER)モジュールでどうなるか図で起こしてみました。
つまり、1.3Vを0%~100%で値が来るようになっています。中間50%が0.65あたりになります。
やるとしてチェックタイミングも今の1秒ですと滑らかではないでしょう。0.2秒程度でやれば、きっとスムーズに度合いを伝えることも可能そうです。
また、ボタンモジュールの場合は0.0と1.3になるので、自分が判定する場合は、50%である0.65あたりをしきい値にON/OFFを判断しています。
かなり泥臭いことをやっている+参考記事
本コードかなり泥臭いことをやっているいます。BLEもkonashiもよくわからないまま進めていたので、まず確実性を高めるためにBLE上の全機器を捜索。しかも、konashiをみつけても油断せず、characteristicsについても全部捜索。該当するものを変数に保持して使う挙句に、PIOについても、とりあえず255を与えて全PINを出力に向けてます。
このあたり、もう少し扱いに慣れてくれば、シンプルにしていきたいところです。
そして、nobleの文献は私としては以下の記事がとても参考になりました。
- 新ファーム機能!EdisonでBLE機器を制御してみた | TONGARISM.COM
- 基礎的にはとてもいいコードだけど、Edisonでやる話なのでkonashiに読み替えないとややハマる
- BLEのアドバタイズを受信する – wonder gadget
- すごくシンプルでありがたい
- nobleでkonashi(koshian)のanalog readの値を読む
- アナログ入力のヒントに
- akita – PukiWiki「
/diary/index.php?akita#cdb50a84」- 「14/11/12: Node.js+nobleでkonashiをつつく」のあたりに、Bufferに255(11111111)を出してPIO SETTINGとPIO OUTPUTする方法が書かれている
ありがたやありがたや。
余談:いろいろBLE接続くり返していると、デジタル出力だけうまくいかないことがある(原因はまだわからず)
これ結構ハマりました。
konashi自体なのかBLE規格のクセかもしれませんが、konashi littleBitsに対していろいろBLE接続くり返していると、デジタル出力だけうまくいかないことがあります。
BLEの専有と解放がうまくいってない予感。 まあ、いろんな機器で取得してみてればそういうこともありますね。
アナログ入力はだいたい取れてるだけに、LEDがつかないわけで、あれー!?コードが悪い???ってなります。
その時は、おちつきましょう。konashiを一旦電源外してOFFにしてリセットしましょう。そうすれば大丈夫でした。
konashi littleBitsの場合はモジュールを一度パチっとはずして付け直します。
littleBitsモジュールにすると、こうやってプラスマイナスを気にせず、気軽に接続を外せて試せるところが素敵なところですね。
また、まれにkonashi littleBitsモジュールの先のOUTPUTモジュールの接触不良ってこともあるので、そのあたりはやっぱり付け直しつつトライアンドエラーで行きましょう。
基本はkonashiを一旦電源外してOFFにしてリセットで、だいたいなんとかなります。
実戦的には、OFFリセット後なるべく単一の機器(この場合Raspberry Piなど)でkonashiとの確保しくというのも大切そうです。
余談:noble以外にもblenoっていうのがあるけど?
npmライブラリ群で似た名前があったりするのはよくあるのですが、よい記事を見つけました。
しかもnodeのモジュールがある。作者もbleaconと同じ人。
※nobleもblenoも作者が一緒!
一緒の方らしいです。すげー。
(他にも気になるライブラリあるなー)
おわりに
いかがでしたでしょうか。
これができると、Raspberry PiがBLEの接続基地として使いつつ、SocketIOサーバーを立てればリアルタイムに色々なことが出来そうです。
それでは、よきRaspberry Pi+NodeJS+BlueTooth Low Energy+littleBits Lifeを!