「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