EdisonでgolangからBLEを扱う¶
Intel Edison が人気です。特に、WiFiとBLEが両方とも使えるのは非常にIoT向きといえるでしょう。
Edisonには標準で NodeJS を使った開発環境が搭載されていますが、やはりここはgolangで扱いたいところです。
paypal/gatt¶
GolangでBLEを扱うには、 github.com/paypal/gatt が最適です。このライブラリはBLEのperipheralの動作などからすべてgolangで実装しており、pure golangで動作します。
以下にサンプルプログラムを記載します。この例では、 mainで gatt.NewDevice でdeviceを作り、 onStateChanged と onPeriphDiscovered という二つの関数をハンドラに登録するだけで、BLE機器の探索が行えます。
func onStateChanged(d gatt.Device, s gatt.State) {
fmt.Println("State:", s)
switch s {
case gatt.StatePoweredOn:
fmt.Println("scanning...")
d.Scan([]gatt.UUID{}, false)
return
default:
d.StopScanning()
}
}
func onPeriphDiscovered(p gatt.Peripheral, a *gatt.Advertisement, rssi int) {
fmt.Printf("\nPeripheral ID:%s, NAME:(%s)\n", p.ID(), p.Name())
fmt.Println(" Local Name =", a.LocalName)
fmt.Println(" TX Power Level =", a.TxPowerLevel)
fmt.Println(" Manufacturer Data =", a.ManufacturerData)
fmt.Println(" Service Data =", a.ServiceData)
}
func main() {
d, err := gatt.NewDevice(option.DefaultClientOptions...)
if err != nil {
log.Fatalf("Failed to open device, err: %s\n", err)
}
// Register handlers.
d.Handle(gatt.PeripheralDiscovered(onPeriphDiscovered))
d.Init(onStateChanged)
select {}
}
paypal/gattを使うことで、golangから簡単にBLEを扱えるのですが、一つ困ったことがあります。
paypal/gattは、 HCI USER CHANNEL を前提としており、これはLinux 3.14以降でのみ搭載されています。つまり、Linux 3.10で動いているEdisonでは、paypal/gattは動作しない、ということになります。
noble¶
しかし、 NodeJSで動作する noble は動くよな、と思い調べていくとnobleは以下の二つの小さなヘルパープロセスをインストール時にbuildし、実行時に使っていることが分かりました。
nobleをインストールすると、以下の二つのバイナリができあがっています。
node_modules/noble/build/Release/hci-ble
node_modules/noble/build/Release/l2cap-ble
その名前の通り、hci-bleがHCIを、l2cap-bleがL2CAPを扱っています。この二つは Bluez のライブラリを直接linkしているため、kernel 3.10でも動作します。
noblechild¶
ここまで調べたところで、思いつきます。
「nobleのヘルパープロセスを使えばPure golangでもkernel 3.10でBLE扱えるんじゃね」
ということで作ったのが noblechild です。
noblechildは、nobleのヘルパープロセスを起動し、nobleと同じようにヘルパープロセスを扱うことで、Pure golangからkernel 3.10でもBLEを扱えるようになります。
使い方¶
nobleをインストールします。
NOBLE_TOPDIR 環境変数を、nobleをインストールしたディレクトリのトップに設定します。
以上です。あとは、ほぼpaypal/gattと同じインタフェースを提供していますので、そのまま使えます。
func main() {
d, err := noblechild.NewDevice(DefaultClientOptions...)
if err != nil {
log.Fatalf("Failed to open device, err: %s\n", err)
}
d.Handle(noblechild.PeripheralDiscovered(onPeriphDiscovered))
d.Init(onStateChanged)
}
まとめ¶
Intel EdisonでgolangからBLEを扱えるようにする noblechild というライブラリを作成しました。
ぶっちゃけハックなので、筋は良くありません。Edisonが3.14に上がれば直接paypal/gattを使えるので、それまでの間のつなぎ、という位置づけと考えています。
golangでBLEを扱えると便利ですね。弊社も関連しているMQTT ゲートウェイの fuji にも搭載し、問題なく動作していますので、そのうち公開したいと思います。
お仕事募集中¶
ツキノワ株式会社 では、BLEやMQTT、Golangに関するお仕事を募集しております。お気軽にお問い合わせください。
Comments
comments powered by Disqus