M5Stackに搭載されているESP32はWi-FiとBluetooth Low Energy(以下、BLE)で通信できます。 「AmbientでIoTをはじめよう」の第10回は、温度、湿度、気圧データをBLEで送信する端末を作ります。 送信したデータはゲートウェイで受信して、Ambientに送りますが、それは次回ご紹介します。

Wi-Fi経由でクラウドに送信する例は「M5Stackでセンサデータを測定し、クラウドに送る (Arduino編)」をご覧ください。

全体の構成

M5Stackに温湿度・気圧センサBME280を接続して、 温度、湿度、気圧を測定し、BLEで送信します。データはゲートウェイで受信してAmbientに送ります。

BLEデバイスの動作

BLEではセンサ端末をペリフェラル、ペリフェラルからデータを取得する端末をセントラルといいます。 スマホから腕時計型の活動量計にアクセスしている場合、活動量計がペリフェラル、スマホがセントラルになります。

BLE通信では、ペリフェラルが自らの存在を発信(アドバタイズ)します。 セントラルはアドバタイジングパケットをスキャンし、自分が必要とするペリフェラルを見つけ、 ペリフェラルに接続(コネクト)してデータの送受信をおこないます。 このやり取りをペリフェラル/セントラルモードあるいはコネクトモードと呼びます。

もう一つの通信方法は、ペリフェラルがセンサデータなどをアドバタイジングパケットに載せて送り、 セントラルがそれを受信する方法です。ブロードキャスター/オブザーバーモードあるいはブロードキャストモードと呼びます。

コネクトモードは双方向通信ができます。 ペリフェラルからセンサデータを受け取るだけでなく、セントラルからペリフェラルのモード設定なども行う場合はコネクトモードを使います。 コネクトモードでは、コネクトしていない時はペリフェラルはアドバタイジングパケットを発信して、セントラルからのコネクトを待ちます。 常にコネクトされるのを待つため、基本的にはDeep Sleepできません。

一方、ブロードキャストモードのペリフェラルは一定時間アドバタイジングパケットに載せてデータを発信し、 後はDeep Sleepするという間欠動作をすることができ、消費電力を低く抑えられます。

今回はブロードキャストモードで動作するセンサ端末を作ります。

センサ端末のハードウェア

M5StackとBME280を使うセンサ端末は「M5Stackでセンサデータを測定し、クラウドに送る (Arduino編)」で開発したものと同じです。 M5StackとBME280は次の表のように接続します。

M5StackBME280モジュール
GNDSDO
SCL(22)SCK
SDA(21)SDI
3V3CSB
GNDGND
3V3Vcore
Vio

前回はジャンパワイヤでM5StackとBME280をつなぎましたが、今回は小さな基板でつないでみました。

M5Stackの概要、M5Stackを使うためのArduinoの環境設定、M5Stackの動作確認については 「M5Stackでセンサデータを測定し、クラウドに送る (Arduino編)」をご覧ください。

ハードウェアの動作確認

マイコンとセンサを接続したら、動作を確認します。

動作確認プログラムも含めて今回のプログラムはGithubに公開しています。

  • AmbientDataInc/EnvSensorBleGw

このページの右上の「Clone or download」>「Download ZIP」をクリックして、ZIPファイルをダウンロードし、 適当な場所で展開します。この中の

  • src/envSensor_esp32/BME280_test/BME280_test.ino

が動作確認プログラムです。

このプログラムをArduino IDEでビルドします。 ビルドの際、Arduino IDEのツール > ボードの設定を「M5Stack-Core-ESP32」に設定することを忘れないでください。

プログラムを実行して、5秒ごとにシリアルとLCDに温度、湿度、気圧が表示されればM5StackとBME280の接続はOKです。

アドバタイジングデータ

ブロードキャストモードはセンサデータをアドバタイジングパケットの中のアドバタイジングデータという領域に載せて発信します。 アドバタイジングデータは次のような構造の最大31バイトのデータで、 Core Bluetooth 4.0 Core Specificationで定義されています。

AD Typeは1バイトのデータで、AD Dataの内容を定義します。 この中にManufacturer Specific(0xFF)という値があり、 AD Dataとして2バイトの企業IDとその企業が定義するデータが入れられます。

企業ID0xFFFFがテスト用に用意されているので、これを使い、次のようなアドバタイジングデータを定義しました。

0長さ10
1AD Type0xFF (Manufacturer Specific)
2Manufacturer ID (low)0xff
3Manufacturer ID (high)0xff
4Sequenceシーケンス番号
5温度 (low)摂氏温度(℃)を100倍した整数値
6温度 (high)
7湿度 (low)相対湿度(%)を100倍した整数値
8湿度 (high)
9気圧 (low)気圧(hPa)を10倍した整数値
10気圧 (high)

温度、湿度を100倍、気圧を10倍して整数にしてアドバタイジングデータとして送信し、 受信側で元に戻すことで、小数点以下2桁、1桁の浮動小数点を2バイトに収めています。

プログラム

プログラムはArduinoで開発します。ESP32のArduinoにはBLEモジュールが提供されており、 プログラミングは「BLE C++ Guide」 という資料に解説されています。

今回開発したプログラムはGithubに公開した中の次のものです。

  • src/envSensor_esp32/BLE_BME280_bcast/BLE_BME280_bcast.ino

BLEの端末側プログラムの主な流れは次のようになっています。プログラム中のコメントを見ると流れが分かると思います。

デバイスを初期化し、サーバを生成し、センサを読んで値をアドバタイジングデータにセットし、T_PERIOD秒アドバタイズします。 その後、S_PERIOD秒休止します。休止中の消費電力を下げるために休止中はDeep Sleepします。 Deep Sleepから復帰するとプログラムは先頭から実行され、次のセンサデータを読み、T_PERIOD秒のアドバタイズをおこないます。

センサを読んで値をアドバタイジングデータにセットする部分は次のようになっています。

2行目でBME280のデータを読み、13〜23行目でアドバタイジングデータを作り、 25、26行目でアドバタイジングデータを設定しています。

アドバタイジングデータにはシーケンス番号を入れています。 シーケンス番号をRTCメモリに定義することで、Deep Sleepの間も値を保持し、1ずつ値を増加させています。

    RTC_DATA_ATTR static uint8_t seq;

動作確認

プログラムをビルドして、端末にダウンロードして動かします。

動作確認にはスマホアプリ「BLE Scanner」を使うのが便利です。

「BLE Scanner」を立ち上げると、スキャンして見つかったBLEデバイスが表示されます。

プログラムが期待通りに動作していれば、デバイスを初期化した時に引数で指定した名前(“AmbientEnv-02”)のデバイスが表示されます。 AmbientEnv-02をタップすると、アドバタイジングデータを確認できます。

Manufacturer Data部分に次のようにデータがセットされているのが確認できます。

2Manufacturer ID (low)0xff
3Manufacturer ID (high)0xff
4Sequence0x93
5温度 (low)0x92
6温度 (high)0x0b → 0x0b92 → 2962 → 29.62℃
7湿度 (low)0xb2
8湿度 (high)0x14 → 0x14b2 → 5298 → 52.98%
9気圧 (low)0x46
10気圧 (high)0x27 → 0x2746 → 10054 → 1005.4hPa

これでブロードキャストモードのセンサ端末ができました。 次回はこのデータを受信してAmbientに送信するゲートウェイを開発します。

この記事はアンビエントデーターの下島が担当しました。