ちょっと癖があるね。
前回まで
RPiのBLEをnobleから叩いてました。
relativelayout.hatenablog.com
今回は、micro:bitのBLE機能を有効にして、RPiからmicro:bitをスキャンしてみようと思います。
relativelayout.hatenablog.com
ちなみに、micro:bitは電池ケースにくっつけて給電できるようにしています。
とりあえずスキャン
フツーにScanすれば良いんですが。
var noble = require('noble')
noble.on('discover', function(peripheral){
console.log(peripheral)
})
noble.startScanning()
startScanning()
のオプションでGATTのサービスのUUIDを指定することができ、これによってスキャン結果をそのサービスがあるペリフェラルにフィルタできるようで。試しにmicro:bitのサービスを指定してスキャンをしてみました。
たとえば、加速度サービスのUUIDはe95d0753-251d-470a-a062-fa1922dfa9a8
なので、
noble.startScanning(['e95d0753251d470aa062fa1922dfa9a8'], false)
みたいに叩けばよいはず。これで叩いてみると・・・なぜかmicro:bitが見つかりません・・・。
接続しないとサービスがわからない?
そんなのもんなのかなぁ思い、改めてオプション無しでstartScanning()
して、見つかったmicro:bitのプロパティを見てみると・・・。
Peripheral {
_noble:
Noble {
(中略)
},
id: 'xxxxxxxxxxxx',
uuid: 'xxxxxxxxxxxx',
address: 'xx:xx:xx:xx:xx:xx',
addressType: 'random',
connectable: true,
advertisement:
{ localName: 'BBC micro:bit [xxxxx]',
txPowerLevel: undefined,
manufacturerData: undefined,
serviceData: [],
serviceUuids: [],
solicitationServiceUuids: [],
serviceSolicitationUuids: [] },
rssi: -33,
services: null,
state: 'disconnected' }
serviceUuids
が空っぽですねぇ。これが空なのでUUIDでフィルタができなかったのでしょうか・・・。とはいえ、localName
にはちゃんとmicro:bitと入っているので、とりあえずワークアラウンドとしてlocalName
でフィルタするしかないんですかね・・・。たとえばこんな感じ。
var noble = require('noble')
noble.on('discover', function (peripheral) {
var localName = peripheral.advertisement.localName
if (localName && localName.startsWith('BBC micro:bit')) {
console.log('micro:bit found!')
}
})
noble.startScanning()
うーん、ちょっとダサいけど、動いてそうだしこれで行くか・・・。