※本記事は、アタラ合同会社 Official noteにて連載中のコラム『BIツールで、働き方改革を実践してみた!』を転載したものです。
今回は番外編で、センサーの中を覗きます
本連載では、これまで環境データの計測用にオムロンの環境センサーを利用してきました。
ところでオムロンの環境センサーは「温度」や「湿度」、「光量」など複数のデータをセンシングできるのですが、番外編として今回は、オムロンの環境センサーで実際にはどのようなデータ構造になっており、どのようにデータを保有しているのかをBLE(Bluetooth Low Energy) 通信で覗いてみようと思います。
※本題の環境構築に移る前に横道に逸れて申し訳ありません(笑)。
用意したもの
2. microSDHCカード 32GB UHS-I CLASS10 *1
3. HDMIケーブル A-D(micro) 1m [RoHS]
4. ACアダプタ DC5V 3A (USB-C)
5. Raspberry Pi ケース Official for Pi 4 B+ 赤/白
6. オムロン 環境センサ(USB型) 2JCIE-BU01
7. キーボード&マウス *2
*1 「Raspbian」というOSをインストール済のカードを購入しました。
※2020年5月に「Raspbian」から「Raspberry Pi OS」に名称変更しました。
*2 必要なのは構築までなので、既存のものを流用しても構いません。
前提
Raspberry Pi(以後、ラズパイ)の環境設定は簡単に調べることができるため割愛しています。事前に準備していただきたい内容は以下の通りです。
ーネットワーク (wifi接続の有効化、固定IPの割り当て、sshサーバー有効化)
ー ソフトウェアのアップデート
BLE通信を試す
まずはセンサーがBLE通信をおこなっているかラズパイ上で、スキャンをしてみます。BLE対応デバイスにはBDアドレスと呼ばれる一意の識別アドレスが設定されています。アドレス情報は、購入した箱に同梱されています。
「hcitool」コマンドでデバイスを検索します。
sudo hcitool lescan
LE Scan ...
69:2F:A3:B5:CC:5A (unknown)
CD:DE:AB:02:35:29 Rbt ← 今回使用するセンサーのアドレス
「gatttool」でBLEデバイスに接続します。
gatttoolとはBluetooth Low Energy のデータの送受信やデータ構造を定義しているGATTのクライアントツールです。これでBLEデバイスの中身を弄ったり覗いたりすることができます。細かい説明については今回は省略します。
※ CD:DE:AB:02:35:29 の部分は対象のアドレスに読み替えてください。
sudo gatttool -t random -b CD:DE:AB:02:35:29 -I
「connect」で接続します。
[CD:DE:AB:02:35:29][LE]> connect
どんなオプションがあるのかヘルプを確認します。
[CD:DE:AB:02:35:29][LE]> help
help Show this help
exit Exit interactive mode
quit Exit interactive mode
connect [address [address type]] Connect to a remote device
disconnect Disconnect from a remote device
primary [UUID] Primary Service Discovery
included [start hnd [end hnd]] Find Included Services
characteristics [start hnd [end hnd [UUID]]] Characteristics Discovery
char-desc [start hnd] [end hnd] Characteristics Descriptor Discovery
char-read-hnd
char-read-uuid
char-write-req
char-write-cmd
sec-level [low | medium | high] Set security level. Default: low
mtu
いろいろとありますが、今回使用するのは primary、characteristics、char-read-hnd の3つです。
環境センサーのユーザーズマニュアルには、どこにどんな情報(センサ値、設定値など)が格納されているかが記載されています。本記事ではある程度マスキングした状態で説明します。
まず「primary」コマンドでセンサーの主要な機能を確認します。
最新のデータは UUID: 0x5010 に格納しています。
[CD:DE:AB:02:35:29][LE]> primary
attr handle: 0x****, end grp handle: 0x**** uuid: ab705000-********
attr handle: 0x****, end grp handle: 0x**** uuid: ab705200-********
attr handle: 0x****, end grp handle: 0x**** uuid: ab705210-********
attr handle: 0x****, end grp handle: 0x**** uuid: ab705400-********
attr handle: 0x0057, end grp handle: 0x0066 uuid: ab705010-********
attr handle: 0x****, end grp handle: 0x**** uuid: ab705110-********
attr handle: 0x****, end grp handle: 0x**** uuid: ab705030-********
attr handle: 0x****, end grp handle: 0x**** uuid: 0000fe59-********
attr handle: 0x****, end grp handle: 0x**** uuid: 0000180a-********
この結果、handle 0057 ~ 0066 に最新データが格納されていることがわかりました。
次に「characteristics」コマンドで最新データの種類を表示します。
マニュアルによると、 UUID: 0x5012 はセンシングデータ、UUID: 0x5013 は計算データとなっています。今回はセンシングデータを対象にします。
[CD:DE:AB:02:35:29][LE]> characteristics 0057 0066
handle: 0x0058, char properties: 0x12, char value handle: 0x0059, uuid: ab705012-********
handle: 0x****, char properties: 0x12, char value handle: 0x****, uuid: ab705013-********
handle: 0x****, char properties: 0x12, char value handle: 0x****, uuid: ab705014-********
handle: 0x****, char properties: 0x12, char value handle: 0x****, uuid: ab705015-********
handle: 0x****, char properties: 0x12, char value handle: 0x****, uuid: ab705016-********
一番上の value handle: 0x0059 にセンシングデータが格納されていることがわかりました。
最後に「char-read-hnd」コマンドで指定したハンドルの値を読み取ります。
[CD:DE:AB:02:35:29][LE]> char-read-hnd 0059
Characteristic value/descriptor: 2f 9b 08 7e 17 b8 00 8d 7d 0f 00 29 0d 87 00 0b 05
よくわからない結果が返ってきました。
データフォーマットを簡単にまとめてみました。温度(Temperature) を例に試してみます。
また、マニュアルにはこのような記載があります。
リトルエンディアンの細かい説明は省略しますが、簡単に言えば「順序が逆になる」ということです。つまり、出力した結果を左から右に入れ替えます。
このようなイメージです。
入れ替え前)2f 9b 08 7e 17 b8 00 8d 7d 0f 00 29 0d 87 00 0b 05
入れ替え後)05 0b 00 87 0d 29 00 0f 7d 8d 00 b8 17 7e 08 9b 2f
温度は1Byteと2Byteで構成されています。今回だと 08 9b が対象です。この16進数を10進数に変換します。
さらに単位が 0.01 degC(摂氏)なので100で割ると22℃であることがわかりました。
このような流れでセンサの値を取得することができますが、やはり相当な労力が必要になる為、プログラミングで自動化するか、ETL製品などでノーコード(またはローコード)で取得できると便利ですよね。
さて、次回は本題に戻り、今回の BLE 通信の接続から取得までの部分をプログラミングしてみましたのでご紹介します!