マイコンESP32-DevKitC-32EとAndroidとのBLE通信
温度センサBMP280ブレイクアウトボード使用

2026.4.17 2023.9.29 Coskx Lab  

1 はじめに

温度センサBMP280を載せたWi-FiマイコンESP32-DevKitC-32Eから,Androidスマホに向けてBLE(Bluetooth Low Energy)を使って,温度情報を送ります。
ESP32-DevKitC-32EはBLE UART Profileを使って通信します。(Bluetooth Classicではありません。)


BLEコネクション通信では,Central(or Master or Observer)とPeripheral(or Slave or Broadcaster)の間で通信が行われます。
ここでは,AndroidをCentral,ESP32-DevKitC-32EをPeripheralとして使うことにします。
ここで使用するAndroidスマホのアプリ"Serial Bluetooth Terminal"は起動の度に,通信相手を探して接続するようになっているため,ペアリング(ボンディング)を必要としていません。 (Peripheral側がペアリング・ボンディングを要求する設定になっている場合は,Central側の通信アプリが接続動作の際にCentral側の設定機構がペアリング・ボンディングを行ないます。)

2 使用環境

3 準備

3.1 ArduinoIDE

(1)Arduino IDEのメニューバーから[ファイルFile] -> [環境設定(Preferences)]
Additional board manager URLsに
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
を設定してOK
(2)ツール[Tools] > ボード[Board] > Boards Manager
検索boxに「ESP」を入力すると複数のボード候補が出てくるので
esp32 by Espressif Systems
をinstall
(3)ツール[Tools] > ボード[Board]でESP32を探すとESP32 Dev Moduleが見つかるので,これを選ぶ。

3.2 ESP32-DevKitC-32E

ESP32-DevKitC-32Eの説明書を読んでプログラムの転送方法を確認します。
(USBケーブルでつないで書き込むだけでした。)

4 ESP32-DevKitC-32Eと温度センサBMP280の配線

温度センサBMP280は温度をデジタル値に変換しているので,そのデータをESP32-DevKitC-32Eが読み出します。
ESP32-DevKitC-32Eと温度センサBMP280はI2C接続ですので,電源線,GND線の他はSCLとSDAの2本のみで通信できます。

CSBをVCCにつなぐとBMP280はI2C接続になります。(データシートによれば確実にVCCにつなぐべきとなっています)
SDO(シルク印刷は間違えていてSDDとなっている)をVCCにつなぐとBMP280のI2Cアドレスは77になります。GNDにつなぐとBMP280のI2Cアドレスは76になります。Groveライブラリのデフォルトは77なのでVCCにつないでいます。

なおBMP280ではSDA,SCLをpullupせずに動作しています。

   ESP32-DevKitC-32Eと温度センサBMP280の配線

   ESP32-DevKitC-32Eと温度センサBMP280

5 ESP32-DevKitC-32Eのスケッチコード(Peripheralプログラム)

central(Androidスマホ)からのリクエストで,PeripheralであるESP32-DevKitC-32Eは,温度センサBMP280の値を取得し,centralに返します。
送受信ではBLE UART通信の手順に従います。

具体的には,ESP32-DevKitC-32Eは文字列"start"を受け取ったら1秒間隔で温度などのデータを送信し,文字列"stop"を受け取ったら送信をやめるようにします。

BLE UART通信ですが,やりたいことは,BMP280の値を取得し送信することですので,BLEの煩雑な部分は,クラスHandy_BLE_Uartに任せて舞台裏に隠れてもらいます。
このプログラムでは受信時にやりたいことを記述した関数は,void StringReceptionReport(String str)としました。送られてくるstrが受信した文字列です。 (受信時にやりたいことを記述した関数の名前は別のものでもOKです)
やりたいこととは,受信した文字列「start」「stop」によりブール変数「requested」のtrue falseを切り替えることです。
ESP32S3側が送信するときは,関数transferString()を使います。

#define DEVICENAME "UART-B0"
は自分の名前です。Androidスマホなどから見つけてもらう名前です。初期化の時点で決定します。

このプログラムではBLE通信の面倒なところをクラスHandy_BLE_Uartにして別ファイルに書いています。

クラスHandy_BLE_Uartの定義は「Handy_BLE_Uart.h」と「Handy_BLE_Uart.cpp」に書かれています。
ダウンロード,解凍して次のプログラムコードBLE_uart_BMP280.inoと同じフォルダに入れてください。

  Handy_BLE_Uartのダウンロード

BLE_uart_BMP280フォルダにプログラムBLE_uart_BMP280.ino,Handy_BLE_Uart.h,Handy_BLE_Uart.cppを入れたところを示します。
そうすると,ArduinoIDEの画面にそれぞれのファイル名が表示されるようになり,クリックするとArduinoIDEでファイルの中を見ることができます。

なお,ペアリング・ボンディングを要求したい場合は,プログラムBLE_uart_BMP280.inoの初期化のときに
bleuart.begin(DEVICENAME, true);
ではなく
bleuart.begin(DEVICENAME, true, 123456);
のように6桁のパスキーを追加します。(パスキーは必ず6桁の数です。)

Arduino IDEでコンパイルするときは,ライブラリ"Grove_-_Barometer_Sensor_BMP280"を予めIDEに追加しておいてください。
これは温度センサBMP280を使うときに必要となるライブラリです。


   BLE_uart_BMP280.inoのプログラムコード

//BLE_uart_BMP280.ino

//ESP32-WROOM-32E
//board: ESP32 Dev Module

#include <Handy_BLE_Uart.h>
#include "Seeed_BMP280.h"

#define DEVICENAME "UART-B0"
#define INTERVAL 1000 //millisec

Handy_BLE_Uart bleuart;
BMP280 bmp280;

void setup() {
  Serial.begin(115200);
  delay(300);

  //start BMP280
  if(!bmp280.init()){
    Serial.println("Device bmp280 error!");
  }

  //受信時に呼び出されるコールバック関数の登録 必須
  bleuart.setCallbackFunc(StringReceptionReport);
  //接続時にCentralに送信するメッセージの設定 必要があったら
  bleuart.setInitialMessage("send me 'start' or 'stop'");
  //初期化 (パスキーによるペアリングを行う場合は6桁(必ず6桁)のパスキーを付ける)
  //引数:自分のデバイス名登録,受信文字列のエコーバックの有無,(パスキー)
  bleuart.begin(DEVICENAME, true);
  //bleuart.begin(DEVICENAME, true, 123456);
  delay(1000);
}

bool requested = false;
bool justrequested = false;

void loop() {
  static int currenttime = 0; //millisec
  static int previoustime = 0; //millisec
  if (bleuart.isConnected()) {
    //Centralに接続中の場合
    if (justrequested) {
      bleuart.transferString("tempreture[degC], pressure[hPa], altitude[m]");
      justrequested = false;
      previoustime = millis(); //elapsed time(ms)
    } else if (requested) {
      currenttime = millis(); //elapsed time(ms)
      if (INTERVAL <= currenttime - previoustime) {
        previoustime += INTERVAL;
        float tempreture = bmp280.getTemperature();
        float pressure = bmp280.getPressure();
        float altitude = bmp280.calcAltitude(pressure);
        char string0[256];
        sprintf(string0, "%.1f, %.0f, %.2f", tempreture, pressure/100.f, altitude);
        bleuart.transferString(String(string0));
      }
    }
  } else {
    requested = false;
  }
  delay(1000);
}

//受信時に呼び出されるコールバック関数
void StringReceptionReport(String str) {
  Serial.println("RX_Value = " + str);
  if (str.indexOf("start") == 0) {
    requested = true;
    justrequested = true;
  } else if (str.indexOf("stop") == 0) {
    requested = false;
    justrequested = false;
  }
}

6 Androidスマホアプリ"Serial Bluetooth Terminal"の準備

Android playから,"Serial Bluetooth Terminal"をダウンロードしてインストールします。

  "Serial Bluetooth Terminal"のアイコン

最初の起動で,メニュー等の探検をします。
〇左上三本線メニューでは
settings→terminal→Show timestampをONにしておくとよいでしょう。
settings→terminal→Buffer sizeは表示内容を保存する作業メモリのサイズです。できるだけ大きくとるのが良いと思います。(200kBでは100文字のデータ約2000行分です。場合によっては無制限もあり)
settings→ReceiveはCR+NLが標準ですが,後で受信行での改行が変だったら,適当に変えてください。
settings→Send→Local echoはONが標準です。自分が送信した文字列も表示されます。
settings→Misc.→Save....は表示内容(LOG)保存先フォルダの設定です。
〇右上3点メニューには
Data→Saveがあって,表示内容を保存の時使います。

7 ESP32-DevKitC-32Eと"Serial Bluetooth Terminal"の通信

先にESP32-DevKitC-32Eに電源を与え,立ち上げておきます。

  "BMP280が接続されたESP32-DevKitC-32E

その後,"Serial Bluetooth Terminal"で 左上三本線メニューでDevices→BluetoothLE→SCAN で付近のBLEデバイスを見つけて表示してくれます。
ここでは,ESP32-DevKitC-32Eのプログラムの
   #define DEVICENAME "UART-B0"
でつけた名前"UART-B0"が見つかるのでこれをタップします。

  Serial Bluetooth Terminalデバイス選択画面

"Serial Bluetooth Terminal"から"start"を送信すると,1秒ごとにデータが送信されてきます。
受信した3つの数値は温度[℃],気圧[hPa],標高[m]を表しています。
"Serial Bluetooth Terminal"から"stop"を送信すると,データ送信が止まります。
画面上の受信データは,右上3点メニューからData→Saveで保存することができます。

"Serial Bluetooth Terminal"から"start"や"stop"を送信するときは,画面下部のテキストボックスに入力して送信ボタンをタップするか,予めマクロボタンに"start"や"stop"の文字列を登録(マクロボタンのタップ&ホールドで登録出来る)しておいて,それらのボタンをタップます。
次の通信画面では,予めマクロボタンに"start"や"stop"の文字列が登録されています。


    Serial Bluetooth Terminal通信画面

8 通信距離

AndroidスマホをCentralとして,ESP32-DevKitC-32Eとの通信距離を測定しました。
見通しの良い直線で50mまで通信可能でした。
それ以上の距離では,通信が途絶えてしまいました。

9 まとめ

Wi-FiマイコンESP32-DevKitC-32EとAndroidスマホでBLEuart通信し,Androidスマホからの指令によって温度などのデータをESP32-DevKitC-32Eが送って来るようにしました。
XIAO ESP32S3側のプログラムでは,BLE通信の面倒なところは,クラスHandy_BLE_Uartに封入して,データ送信部分に専念したプログラムコードに集中できるようにしました。

この記事ではAndroidスマホのアプリ"Serial Bluetooth Terminal"を使いましたが,他にも"Bluefruit Connect"というアプリがあり,同じような使い方が出来ます。iPhoneにもアプリ"Bluefruit Connect"がありAndroid版"Bluefruit Connect"と同じ使い方ができます。
WindowsPCにも同様なアプリ"BLE_serial_terminal"があり,同様の使い方ができます。

次の2つの解説記事は,ESP32SのBLEuart通信を扱っていますが,通信相手がiPhoneあるいはWindowsPCの場合の通信例がありますので,参考になると思います。
  iOSデバイス版の解説
  WindowsPC版の解説