「Raspbian「stretch」上にGO言語をインストール」でGo言語をインストールしましたが、今回はSensorTagから温度情報を入力します。アプリはWindows10上のVisual Studio Codeで開発し、Raspberry Pi上で動作させます。なお、使用するSensorTagについては「Bluez を使用したSensorTagへのアクセス」を参照してください。
開発環境
- Raspbian:buster
- go言語のバージョン:go1.13.4
- コーディング環境:Visual Studio Code 1.44.2
SensorTagの仕様説明
CC2541 SensorTagのデバイス名は、「SensorTag」で、温度データの取得するためのUUIDは、次のようになっています。
- サービスUUID : F000AA00-0451-4000-B000-000000000000
- データUUID : F000AA01-0451-4000-B000-000000000000
- 通知UUID : F000AA02-0451-4000-B000-000000000000
Go言語パッケージのインストール
次のコマンドでBLE用のパッケージ「gatt」をインストールします。
4.BLE paypal/gatt のインストール
$ go get github.com/paypal/gatt
パッケージ「gatt」
BLE機能を持つパッケージで、詳細については「package gatt」に示します。
アプリの作成
作業フォルダ「goble」に次に示す「blemain.go」を作成します。
- 27行目のonPeriphDiscoveredはBEL機器を検出すると、制御が移ります。BLE機器がSensorTagかを調べます。
- 35行目のonPeriphConnectedはSensorTagと接続すると制御が移ります。
- 74行目のonPeriphDisconnectedはSensorTagと切断したときに制御が移ります。
- 15行目でBEL機器をスキャンします。
- 76行目でチャンネル「done」をcloseすることにより、97行目のチェンネルにデータが送信されてプログラムが終了します。
- 66行目で通知を「ON」にします。
- 57行目で通知されてきたデータを受け取ります。
blemain.go
package main
import (
"log"
"github.com/paypal/gatt"
)
var done = make(chan struct{})
var uartServiceId = gatt.MustParseUUID("f000aa00-0451-4000-b000-000000000000")
var uartServiceRXCharId = gatt.MustParseUUID("f000aa02-0451-4000-b000-000000000000")
var uartServiceTXCharId = gatt.MustParseUUID("f000aa01-0451-4000-b000-000000000000")
func onStateChanged(d gatt.Device, s gatt.State) {
log.Println("State:", s)
switch s {
case gatt.StatePoweredOn:
log.Println("scanning...")
d.Scan([]gatt.UUID{}, false)
return
default:
d.StopScanning()
}
}
func onPeriphDiscovered(p gatt.Peripheral, a *gatt.Advertisement, rssi int) {
if a.LocalName == "SensorTag" {
log.Printf("Preipheral Discovered: %s \n", p.Name())
p.Device().StopScanning()
p.Device().Connect(p)
}
}
func onPeriphConnected(p gatt.Peripheral, err error) {
log.Printf("Peripheral connected\n")
services, err := p.DiscoverServices(nil)
if err != nil {
log.Printf("Failed to discover services, err: %s\n", err)
return
}
for _, service := range services {
if service.UUID().Equal(uartServiceId) {
log.Printf("Service Found %s\n", service.Name())
cs, _ := p.DiscoverCharacteristics(nil, service)
for _, c := range cs {
if c.UUID().Equal(uartServiceTXCharId) {
log.Println("TX Characteristic Found")
p.DiscoverDescriptors(nil, c)
p.SetNotifyValue(c, func(c *gatt.Characteristic, b []byte, e error) {
log.Printf("UUID: %s notified: % X | %q\n", c.UUID().String(), b, b)
//log.Printf("Got back %s\n", string(b))
})
}
}
for _, c := range cs {
if c.UUID().Equal(uartServiceRXCharId) {
log.Println("RX Characteristic Found")
p.WriteCharacteristic(c, []byte{0x01}, true)
log.Printf("UUID: %s Wrote %s\n", c.UUID().String(), string([]byte{0x01}))
}
}
}
}
}
func onPeriphDisconnected(p gatt.Peripheral, err error) {
log.Println("Disconnected")
close(done)
}
func main() {
var DefaultClientOptions = []gatt.Option{
gatt.LnxMaxConnections(1),
gatt.LnxDeviceID(-1, false),
}
d, err := gatt.NewDevice(DefaultClientOptions...)
if err != nil {
log.Fatalf("Failed to open device, err: %s\n", err)
return
}
d.Handle(
gatt.PeripheralDiscovered(onPeriphDiscovered),
gatt.PeripheralConnected(onPeriphConnected),
gatt.PeripheralDisconnected(onPeriphDisconnected),
)
d.Init(onStateChanged)
<-done
log.Println("Done")
}
アプリの実行
次のコマンドで作成したアプリをコンパイルして実行します。SensorTagのボタンを押すと、SensorTagとRaspberry Piが接続され、Notify転送により1秒周期で温度データがSensorTagから転送されます。もう一度SensorTagのボタンを押すと、切断されてプログラムが終了します。
$ go build $ sudo ./goble 2020/05/09 14:43:36 dev: hci0 up 2020/05/09 14:43:36 dev: hci0 down 2020/05/09 14:43:36 dev: hci0 opened 2020/05/09 14:43:37 State: PoweredOn 2020/05/09 14:43:37 scanning... 2020/05/09 14:43:39 DATA: [ 50 00 20 03 ] 2020/05/09 14:43:39 Preipheral Discovered: SensorTag 2020/05/09 14:43:39 Peripheral connected 2020/05/09 14:43:40 Service Found 2020/05/09 14:43:40 TX Characteristic Found 2020/05/09 14:43:40 RX Characteristic Found 2020/05/09 14:43:40 UUID: f000aa0204514000b000000000000000 Wrote 2020/05/09 14:43:40 UUID: f000aa0104514000b000000000000000 notified: 43 FF 94 0B | "C\xff\x94\v" 2020/05/09 14:43:41 UUID: f000aa0104514000b000000000000000 notified: C4 FF 94 0B | "\xc4\xff\x94\v" 2020/05/09 14:43:42 UUID: f000aa0104514000b000000000000000 notified: 68 00 98 0B | "h\x00\x98\v" 2020/05/09 14:43:43 UUID: f000aa0104514000b000000000000000 notified: B3 FF 98 0B | "\xb3\xff\x98\v" 2020/05/09 14:43:44 UUID: f000aa0104514000b000000000000000 notified: E6 FE 94 0B | "\xe6\xfe\x94\v" 2020/05/09 14:43:45 UUID: f000aa0104514000b000000000000000 notified: F3 FF 98 0B | "\xf3\xff\x98\v" 2020/05/09 14:43:45 Disconnected 2020/05/09 14:43:45 Done