JavaScript
js
bluetooth
BLE
バイナリ

[応用編]JavaScriptでバイナリデータを扱ってみる~Bluetoothの温度データ形式を理解する~(1/3)

More than 1 year has passed since last update.

BRIGHT VIE Advent Calendar 2017 - Qiita 4日です。

昨日は、「[基礎編]JavaScriptでバイナリデータを扱ってみる」というタイトルで、JavaScriptでのバイナリデータの扱い方の基礎を記載しました。
本日からは、3回に分けて実際にBluetoothの仕様で定義されているデータ形式を元に実際の生データを扱ってみたいと思います。

はじめに

いきなりですが、まずはこちらを御覧ください。

BLE_Temperature Measurement.png

[引用元] Temperature Measurement - Assigned Number: 0x2A1C Bluetooth

こちらは、Bluetoothで温度のやりとりをする際の共通フォーマットが上記のように定義されております。

Bluetooth Temperature Measurementのフォーマットを読み解いてみる

Flags

まず、1バイト目に記載されている「Flags」にて

1ビット目: 温度の設定

説明 形式
0の場合 Celsius: 摂氏(°C) C1のフィールドを参照
1の場合 Fahrenheit: 華氏(°F) C2のフィールドを参照

2ビット目: 計測時間の記録有無

説明 形式
0の場合 設定なし
1の場合 設定あり C3のフィールドを参照

3ビット目: 温度のタイプ設定の有無

説明 形式
0の場合 設定なし
1の場合 設定あり C4のフィールドを参照

4~8ビット: 設定なし

現在は利用されていないが、今後仕様が追加されたときのための予約フィールドとして指定されている。

C1: Temperature Measurement Value (Celsius)

Flagsの1ビット目が0の場合、「Celsius: 摂氏(°C)」での温度が設定されています。
保存されているデータのフォーマット形式が、「FLOAT」であるため、
下記記事の定義より「IEEE-11073 32-bit FLOAT」であることがわかります。

[引用元]Format Types - Bluetooth

https://www.bluetooth.com/specifications/assigned-numbers/units

C2: Temperature Measurement Value (Fahrenheit)

Flagsの1ビット目が1の場合、「Fahrenheit: 華氏(°F)」での温度が設定されています。
C1の摂氏(°C)の場合と同様にフォーマット形式が、「FLOAT」であるため、
こちらも「IEEE-11073 32-bit FLOAT」であることがわかります。

C3: Time Stamp

Flagsの2ビット目が1の場合、このフィールドには「温度を計測したときの時間」が設定されています。
形式は、「org.bluetooth.characteristic.date_time」と記載されており、
引用元の定義より、下記のような7バイトのフォーマットで計測時間が記録されています。

Day of Month is not known.png

[引用元]
Date Time - Assigned Number: 0x2A08

C4: Temperature Type

最後にFlagsの3ビット目が1の場合、このフィールドには「温度のタイプ」(計測時の状況)が設定されています。
形式は、「org.bluetooth.characteristic.temperature_type」と記載されており、
引用元の定義より、下記のような1バイトのフォーマットで計測時間が記録されています。

Name_Temperature_Type.png

[引用元]Temperature Type - Assigned Number: 0x2A1D

フローチャート

次にプログラムの処理を考えるため、フローチャートを記載してみます。

Flagsのビットパターン別状態チェック.png

このようにロジックを記載すれば解析可能です。
また、参考程度に1バイト目のFlagsのビットパターン別に、どのようにデータが保存されているか可視化してみました。

Flagsのビットパターン別メモリ状態.png

結構簡単ですね!

まとめ

ここまでBluetooth経由で温度データを受信する際の共通フォーマット及び処理フローが理解できたかと思います。
次の記事では、上記フローをもとに生データを扱ってみたいと思いますが、
ここで1つ疑問に思われていることがあるのではないでしょうか?

それは、
「摂氏(°C)」「華氏(°F)」ともにそうですが、「Temperature Measurement Value」がFLOATと定義されていますが、
「IEEE-11073 32-bit FLOAT」というところ...

FLOATとは、浮動小数点のことを指しており、小数点を扱うためのデータフォーマットです。
昨日の記事でも、JavaScriptで「32ビット浮動小数点数」を扱うときは
DataViewクラスの「getFloat32」や「setFloat32」を利用すれば良かったはずです。

よく資料を見てみると

Format short Name Description
0x14 float32 IEEE-754 32-bit floating point
0x15 float64 IEEE-754 64-bit floating point
0x16 SFLOAT IEEE-11073 16-bit SFLOAT
0x17 FLOAT IEEE-11073 32-bit FLOAT

[引用元]Format Types - Bluetooth

IEEE-754で定義されているfloatとIEEE-11073で定義されているFLOAT
どちらも小数点を扱うデータフォーマットですが何が違うのか...

明日の記事ではこのあたりの部分を明確にしていきたいと思います。