TI社のSensorTagで温度、湿度、気圧、照度、バッテリーレベルを測りBluetooth Low Energy(BLE)でRaspberry Pi3(RPi3)に送り、RPi3からIoTデーター可視化サービス「Ambient」に送ってデーターをグラフ化しました。その1はBLEをスキャンして、見つけたSensorTagのデーターを読み取り、Ambientに送信することを5秒ごとに繰り返すという単純なものでしたが、今回は複数台のSensorTagに対応し、読み取り間隔も5分にしました。コイン電池駆動で長期間の測定に挑戦しています。
SensorTag
SensorTagは通信モジュールの異なる3種類のデバイスがあります。今回使ったのは「マルチスタンダード SensorTag」というもので、BLEで通信します。センサーとしては周囲および表面の温度センサー、湿度センサー、気圧センサー、周辺光センサー、加速度センサー、ジャイロスコープ、コンパス、磁気センサーが搭載されていて、ボタン電池(CR2032)1個で動作します。
SensorTagはBLEで通信するので、Raspberry Pi3(RPi3)をゲートウェイとして使い、RPi3からBLEでSensorTagのデーターを取得し、Ambientに送ることにしました。
BLE通信では、端末(Peripheral)がアドバタイズデーターを送信し、セントラル側でそれをスキャンして、必要な端末を見つけ、そこに接続してデーターの送受信を行います。
SensorTagはアドバタイズデーターを送信して2分間接続がないと、スリープモードに移行し、消費電力を抑えます。スリープモードに入ると通信をしないためセントラル側からは端末を起こすことができず、端末の電源ボタンをクリックすることでアドバタイズモードに復帰します。
SensorTagは1台のセントラルとしか接続できないので、複数のセントラルと接続するような使い方の場合はアドバタイズモードで待つ必要がありますが、環境センサーとして使う場合はセントラルとして1台のゲートウェイだけに接続すれば大丈夫です。ゲートウェイに接続したまま、定期的に測定データーを取得するようにすると、取得間隔は2分以上でもスリープモードには移行しません。何らかの理由で接続が切断された場合は再接続するようにします。
その1では「SensorTagはアドバタイズ状態で2分間放っておくとスリープモードに入って通信できなくなるので、長期間測定する端末としては使いにくい」と書きましたが、接続したままにすればスリープモードには入らないので、長期間測定する端末としても問題なく使えることが分かりました。
Raspberry Pi3(RPi3)上のプログラム
RPi3上のプログラムはPythonで書きました。大まかな動作は次のようです。
1.BLEをスキャンし、SensorTagを探す
2.SensorTagを見つけたら、接続し、5分に1回、温度、湿度、気圧、照度、バッテリーレベルを測定し、Ambientに送信する
3.SensorTagとの接続が切断された場合は再接続し、測定を継続する
複数台のSensorTagを扱えるように、SensorTagを見つけたらSensorTag毎に独立したスレッドを起動し、一つのスレッドが一つのSensorTagに接続して通信するようにします。
また、PythonでWebサーバーを動かし、SensorTag設定ポータルを立ち上げました。Ambientに送信する際のチャネルIDとライトキーをプログラム中に記述せず、ブラウザーから設定できるようにしました。
RPi3上のプログラムの構成を図示すると次のようになります。
RPi3の環境構築
BLEをアクセスするライブラリーとしてbluepyを使いました。このライブラリーはドキュメントもしっかりしており、SensorTagをアクセスするモジュールも含まれているのでお薦めです。
まずbluepyをRPi3にインストールします。
pi$ cd /var
pi$ sudo mkdir -p www/html
pi$ cd www/html
pi$ sudo apt-get install python-pip libglib2.0-dev
pi$ git clone https://github.com/IanHarvey/bluepy.git
pi$ cd bluepy
pi$ python3 setup.py build
pi$ sudo python3 setup.py install
pi$ cd bluepy
pi$ cp blescan.py btle.py bluepy-helper __init__.py sensortag.py uuids.json ../..
ブラウザーからAmbientのチャネルIDとライトキーを設定するようにしました。このためにHTTPのリクエストハンドラーからSensorTagと通信するメインのプログラムに対してデーターを受け渡す必要があります。プロセス間通信の方法はいろいろありますが、今回はPythonと親和性がよさそうなRedisを使いました。そこで、RedisとRedisのPythonライブラリーをインストールします。
pi$ sudo apt-get install redis-server
pi$ sudo pip3 install redis
最後にAmbientのPythonライブラリーもインストールします。
pi$ sudo pip3 install git+https://github.com/TakehikoShimojima/ambient-python-lib.git
PythonプログラムとSensorTag設定ポータルに必要なファイルはGithubに公開しました。
pi$ cd /var/www/html
pi$ sudo wget https://github.com/TakehikoShimojima/sensortag-ambient/archive/master.zip
pi$ sudo unzip master.zip
pi$ cd sensortag-ambient-master
pi$ sudo chmod +x cgi-bin/sensortaglist.py cgi-bin/result.py
pi$ sudo mv * ..
pi$ cd ..
起動
RPi3上でBLEをアクセスするプログラムを動作させるにはroot権限が必要なので、プログラムは次のように動かします。
pi$ sudo python3 st2ambient2.py -v
RPi3からログアウトするとプログラムは終了してしまうので、ログアウトしても動かし続けるには次のようにします。
pi$ sudo nohup python3 st2ambient2.py -v < /dev/null &
プログラムのオプションは次の二つです。
- -i n:測定間隔をn秒で指定します。省略時は300秒(5分)間隔になります。
- -v:動作状況を出力します。
プログラムが動き出してしばらくするとSensorTagを見つけます。-vオプションをつけて起動した場合、次のようなメッセージが表示されます。
New SensorTag 24:71:89:bc:63:84
「New SensorTag」の後ろはその端末のMACアドレスです。
SensorTagが見つからない場合は、一度SensorTagの電源ボタンを3秒以上押して端末をオフにして、その後もう一度電源ボタンをクリックしてください。アドバタイズが開始され、SensorTagの緑のLEDが1秒間隔で点滅を始めます。しばらくするとプログラムが端末を見つけるはずです。
端末を見つけたら、ブラウザーからRaspberry Pi3のアドレスに接続します。すると次のようなSensorTag設定ポータルが表示され、見つけた端末のMACアドレスと信号強度(rssi)が表示されます。
この画面でデーターを送信するAmbientのチャネルIDとライトキーを入力し、設定ボタンをクリックすると、チャネルIDとライトキーがPythonプログラムに渡され、測定データーがAmbientに送信されます。
Ambientで確認すると、次のように測定したデーターを確認することができます。