もみあげあしめ

組み込みとかIoTとか、いろいろ

Fitbit Charge HRとBLEで通信する

前回からの続きの記事になります。
失敗したままでは終われない!そう誓った5分後、早速失敗の原因を見つけたのでした。

f:id:shima_nigoro:20160603232120p:plain:w300

この記事では、Raspberry Pi 2 を使って Fitbit Charge HR と通信する方法について
まとめたかったのですが、結局コアな部分は非公開のため心拍数等は取れませんでした。

そのため、この記事では

を Fitbit Charge HR で BLE 通信する例としてまとめてみました。
※一応、BLE 規格についても補足程度には書いています。

1. kernelと OS のバージョンを更新する

kakakikikekeのブログ: RaspberryPi で Error: connect: Connection refused (111)
によると OS と kernel のいずれかのバージョンが低いと、通信に失敗するようです。

・とりあえず諸々をアップデート

sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade

#本当にアップデート必要なのか?

リポジトリ変更前のバックアップ

sudo cp /etc/apt/sources.list{,.wheezy}

リポジトリを書き換えるため「/etc/apt/sources.list」を編集して下記を追加する

deb http://mirrordirector.raspbian.org/raspbian/ jessie main contrib non-free rpi

ちなみに前のバージョンのものはコメントアウトしておくので下記のような感じになる

#deb http://mirrordirector.raspbian.org/raspbian/ wheezy main contrib non-free rpi
deb http://mirrordirector.raspbian.org/raspbian/ jessie main contrib non-free rpi
# Uncomment line below then 'apt-get update' to enable 'apt-get source'
#deb-src http://mirror.ox.ac.uk/sites/archive.raspbian.org/archive/raspbian/ wheezy main contrib non-free rpi

・下記コマンドで OS と kernel をアップデート

sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade

#軽く2時間くらいかかると思っておいたほうがいい。
 間に設定ファイルをそのまま利用するか等の確認が入ることもあるので意外に面倒。

・アップデート後は再起動

sudo reboot


2. ソースコンパイルした BlueZ のアンインストール

※インストールしていなければ不要
ソースコードをビルドしたディレクトリで下記コマンドを実行

sudo make uninstall

・コピーした gatttool も消しておく

sudo rm /usr/bin/gatttool


3. BlueZ のインストール

・下記コマンドで一発

sudo apt-get install bluetooth bluez blueman


4. BLEのUSBドングルを確認する

今回もこれを使います。

・ドングルを差し込んで lsusb で認識するか確認

lsusb

繋がっていれば下記のような感じの結果が表示される

Bus 001 Device 005: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)

・繋げただけだと通信できないので、通信可能な状態にする

sudo hciconfig hci0 up

・下記コマンドで「UP RUNNING PSCAN」が表示されればOK

hciconfig


5. BLEデバイスを探してみる

BLEで通信できるデバイスは、Advertising パケットと呼ばれるパケットを
一定周期で飛ばしているので、下記コマンドでそれを拾って表示する。

sudo hcitool lescan

Fitbit Charge HR は 次のように表示されるMAC はとりあえず伏字にしておく

LE Scan ...
XX:XX:XX:XX:XX:XX (unknown)
XX:XX:XX:XX:XX:XX Charge HR
:


6. BLEデバイス(今回はFitbit Charge HR)に接続する

・スキャンした時のMACアドレスを使って接続する(-Iで対話モード)

sudo gatttool -b XX:XX:XX:XX:XX:XX -I

※gatttool の対話モードが始まると「[XX:XX:XX:XX:XX:XX][LE]>」が表示されます。

・下記コマンドで接続

[XX:XX:XX:XX:XX:XX][LE]>connect

・下記のような表示が出て無事、接続できませんでした!

Attempting to connect to XX:XX:XX:XX:XX:XX
Error: connect error: Transport endpoint is not connected (107)

めでたしめでたし。


…ではなくてですね。

・コマンドを下記のように変更します。

sudo gatttool -t random -b XX:XX:XX:XX:XX:XX -I

・もう一度、下記コマンドを実行すると

[XX:XX:XX:XX:XX:XX][LE]>connect

・下記のような表示が出て無事、接続できました!

Attempting to connect to XX:XX:XX:XX:XX:XX
Connection successful


7. BLEデバイスのデータを取得する

バイスへの接続に使った gatttool で引き続きデバイスのデータを取得してみます。

コマンド 説明 備考
help ヘルプを表示 コマンド一覧の表示
exit 対話モード を終了する -
quit 対話モード を終了する 私はこっち派
connect 接続する -
disconnect 切断する -
primary Primary Service Discovery を行う -
characteristics Characteristics Discovery を行う -
char-read-hnd handle を指定して Characteristic を読む -


ちなみにBLEにおけるGATTのデータ構造は下図のとおり(図は規格から抜粋)
データ取得は Service に含まれる Characteristic の Value(Descriptor)を読むことで行います。
f:id:shima_nigoro:20160604000833p:plain:w500

7.1. Fitbit Charge HRに接続して Primary Service Discovery してみる
[XX:XX:XX:XX:XX:XX][LE]> primary
attr handle: 0x0001, end grp handle: 0x0007 uuid: 00001800-XXXX-XXXX-XXXX-XXXXXXXXXXXX
attr handle: 0x0008, end grp handle: 0x000b uuid: 00001801-XXXX-XXXX-XXXX-XXXXXXXXXXXX
attr handle: 0x000c, end grp handle: 0x0017 uuid: adabfb00-XXXX-XXXX-XXXX-XXXXXXXXXXXX
attr handle: 0x0018, end grp handle: 0x001b uuid: 558dfa00-XXXX-XXXX-XXXX-XXXXXXXXXXXX
attr handle: 0x001c, end grp handle: 0x0021 uuid: 0000180a-XXXX-XXXX-XXXX-XXXXXXXXXXXX
attr handle: 0x0022, end grp handle: 0xffff uuid: 0000180f-XXXX-XXXX-XXXX-XXXXXXXXXXXX

uuid を見れば service の attribute が何を表しているかわかる。※定義されているならば

uuid 内容 備考
00001800- Generic Access 汎用的なアクセス方法
00001801- Generic Attribute 汎用的な属性
adabfb00- おそらく独自 Service -
558dfa00- おそらく独自 Service -
0000180a- Device Information バイスに関する情報
0000180f- Battery Service バッテリーに関するサービス

参照:Services | Bluetooth Development Portal

7.2. Characteristics Discovery してみる

・Service の handle を使って Characteristic を確認する

[XX:XX:XX:XX:XX:XX][LE]> characteristics 0x001c
handle: 0x001d, char properties: 0x02, char value handle: 0x001e, uuid: 00002a29-XXXX-XXXX-XXXX-XXXXXXXXXXXX
handle: 0x0020, char properties: 0x02, char value handle: 0x0021, uuid: 0000fb00-XXXX-XXXX-XXXX-XXXXXXXXXXXX
handle: 0x0023, char properties: 0x12, char value handle: 0x0024, uuid: 00002a19-XXXX-XXXX-XXXX-XXXXXXXXXXXX
uuid 内容 備考
00002a29- Manufacturer Name String 製造者名の文字列
0000fb00- 不明 -
00002a19- Battery Level 電源のレベル

参照:Characteristics | Bluetooth Development Portal

7.3. Characteristic に割り当てられた 値(Value)を読んでみる

・Characteristic の value 用 handle を使って Value を確認する

[XX:XX:XX:XX:XX:XX][LE]> char-read-hnd 0x001e
Characteristic value/descriptor: 46 69 74 62 69 74 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[XX:XX:XX:XX:XX:XX][LE]> char-read-hnd 0x0024
Characteristic value/descriptor: 00

「Manufacturer Name String」は ASCIIコードなので「46 69 74 62 69 74 00」は「F i t b i t \0」ですね。
「Vattery Level」はまさかの00。取得できないようにされているんですかね…。

8. リアルタイムで計測データを取得したかった

心拍数等のデータはおそらく独自サービスだけで取得できるようになっていると思われます…。
残念ながら、Sniffer等を使って通信データを分析しない限り、リアルタイムのデータは取れないです。

最後に

Bluetoothの規格について知りたい方は https://www.bluetooth.com/specifications/adopted-specifications
Core Version 4.2 に詳細が書かれていますが、すべてを理解することは難しいと思います…。

BLE黎明期はネットを探しても情報が少なかったので、下記の洋書がとても役に立ちました。
概要を理解するためには、とても良い本であると思います。

Bluetooth Low Energy: The Developer's Handbook

Bluetooth Low Energy: The Developer's Handbook