
新ファーム機能!EdisonでBLE機器を制御してみた
前回、EdisonでBLE機器が検索できることを確認したので、Edisonを使ってBLE機器の制御を行ってみたいと思います。
環境準備
使用機器
使用したのは、iPhoneや家の鍵などの紛失を防ぐためのキーホルダー型Bluetooth機器です(以下、探せるキーホルダー)。専用アプリを使用してiPhoneからブザーを鳴らしたり、指定した距離を離れた際に、振動して知らせる機能があります。
商品情報では”iPhone専用”となっていますが、Edisonからの制御ができるのか、試してみたいと思います。
iBUFFALO Bluetooth4.0+LE対応 iPhone4S専用探せるキーホルダー BSHSBTPT01BK
無線インターフェース:Bluetooth Ver4.0 + LE
対応機器:iPhone4S、iPhone5S、iPhone5C
対応プロファイル:PXP(近接プロファイル)、FMP(Find Meプロファイル)
Edisonへのnobleインストール
nobleは、node.jsを使用してbluetooth制御を行うためのモジュールです。Edisonにも対応しているため、TONGARISMではnobleを使用して、探せるキーホルダーとの通信を行いました。
nobleは、以下のコマンドでインストールすることができます。
npm install noble |
対応機能を調べてみる
BLEの制御を行うために、まずは探せるキーホルダーがどんな機能に対応しているかを調べてみたいと思います。
BLEの通信仕様では、デバイスの中にServiceと呼ばれる機能のまとまりがあり、さらにその中にCharacteristicと呼ばれる細かい複数の機能が存在します。
使用する機器がどのようなService、Characteristicに対応しているかを知ることで、その機器に対して何ができるのを知ることができます。
対応機能取得プログラム
nobleのI/F仕様を参考に、対応しているServiceとCharacteristicを取得するコードを作成しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
var noble = require('./index'); console.log('noble'); 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'); }); noble.on('discover', function(peripheral) { //advertising data受信時のcalback処理 console.log('on -> discover: ' + peripheral); noble.stopScanning(); peripheral.on('connect', function() { console.log('on -> connect'); this.discoverServices(); //connect完了で、discover実施 }); peripheral.on('disconnect', function() { console.log('on -> disconnect'); }); peripheral.on('servicesDiscover', function(services) { for(i = 0; i < services.length; i++) { console.log('service[' + i + '] ' + services[i]); services[i].on('includedServicesDiscover', function(includedServiceUuids) { console.log('on -> service included services discovered ' + includedServiceUuids); this.discoverCharacteristics(); //Service毎のcharacteristicをdiscover実施 }); services[i].on('characteristicsDiscover', function(characteristics) { for(j = 0; j < characteristics.length; j++) { //Service毎のcharacteristicを表示 console.log('service_uuid ' + characteristics[j]._serviceUuid + ' characteristic[' + j + '] ' + characteristics[j]); } }); services[i].discoverIncludedServices(); } }); peripheral.connect(); //機器との接続実施 }); |
取得結果
取得した結果、探せるキーホルダーは以下のようなService、Characteristicに対応していることがわかりました。
Service | Characteristic | アクセス方法 | 概要 |
---|---|---|---|
Generic Access | Device Name | read | デバイス名 |
Appearance | read | 製品カテゴリ | |
Peripheral Preferred Connection Parameters | read | 接続パラメータ | |
Link Loss | Alert Level | read/write | 機器接続が切れた際の動作 |
Immediate Alert | Alert Level | writeWithoutResponse | ブザー鳴動などのアラーム動作 |
Tx Power | Tx Power Level | read | 送信電力 |
Battery Service | Battery Level | read | バッテリー残量 |
BLE機器の制御
次に、先ほどの取得結果から
- デバイス名の取得
- アラームの鳴動
- バッテリー残量の取得
を行ってみたいと思います。
プログラム
BLEの制御は、使用したい機能のCharacteristicに対してデータを読み書きすることで行われます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
var noble = require('./index'); console.log('noble'); 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'); }); noble.on('discover', function(peripheral) { console.log('on -> discover: ' + peripheral); noble.stopScanning(); peripheral.on('connect', function() { console.log('on -> connect'); this.discoverServices(); }); peripheral.on('disconnect', function() { console.log('on -> disconnect'); }); peripheral.on('servicesDiscover', function(services) { //各サービスを登録 var genericAccessService = services[0]; var immediateAlertService = services[2]; var BatteryService = services[4]; immediateAlertService.on('characteristicsDiscover', function(characteristics) { //writeWithoutResponseとして、データ送信する characteristics[0].write(new Buffer([1]), true); }); genericAccessService.on('characteristicsDiscover', function(characteristics) { characteristics[0].on('read', function(data, isNotification) { console.log('DeviceName:' + data); }); //デバイス名を取得する characteristics[0].read(); }); BatteryService.on('characteristicsDiscover', function(characteristics) { characteristics[0].on('read', function(data, isNotification) { console.log('Battery Level = ' + data[0]); }); //バッテリー残量を取得する characteristics[0].read(); }); //各サービスのcharacteristicをdiscover実施 immediateAlertService.discoverCharacteristics(); genericAccessService.discoverCharacteristics(); BatteryService.discoverCharacteristics(); }); peripheral.connect(); }); |
実行結果
デバイス名(BSHSBTPT01BK)・バッテリー残量(100%)の取得、バイブ鳴動を行うことができました!
次回は…
iPhoneアプリのように、離れたらアラームが鳴動する機能を動作させてみたいと思います。