😽

ESP32とスマホでBLE通信をする.そしてロボットを動かす.

に公開

はじめに

この記事は弊ロボコンサークルの初心者向け教育資料として、大量にあったESP32-S3を使って最小構成機体を動かしてもらうために作成しました。筆者自体も初心者なので、拙い部分は大目に見てください。

ESP32はBluetoothが使えます.今回は,ESP32-S3-devkitc-1を使います.
ESP32-S3は,BLE通信のみで,PS4などのclassicBluetoothは使えません.
そこで今回は,スマホアプリ”MicroBlue”を使って,ESP32とスマホ間でBLE通信を試みます.


0. 使用するロボットとブロック図と回路図

ブロック図

パワー配線

制御配線

1. 環境構築

ESP32用のArduino環境をセットアップ

まず、ESP32-S3をArduino IDEで使えるようにします。

  1. Arduino IDEのインストール

  2. ESP32ボードマネージャのインストール

    • Arduino IDEを開く
    • [ファイル] → [環境設定] を開く
    • 追加のボードマネージャのURL に以下を入力:
      https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
      
    • [ツール] → [ボード] → [ボードマネージャ] を開き、「ESP32」を検索
    • 「esp32 by Espressif Systems」をインストール
  3. ESP32-S3用のボードを選択

    • [ツール] → [ボード] から "ESP32S3 Dev Module" を選択

3. ESP32-S3のスケッチ

iPhoneとESP32-S3をBLE通信させるには、ESP32を BLE Peripheral(サーバー) として動作させ、iPhone側を BLE Central(クライアント) として操作します。

コードと使用例

以下のリポジトリから、"myBLEController.h"、"myBLEController.cpp"をダウンロードして、
main.inoと同じディレクトリに配置して下さい。

https://github.com/takaki-maeda-99/takaki-works-hub/tree/main/Training/Intro/main

使用例

以下では、タイマー割込みでBLE通信を読み取りを行っています。
スマホから飛んでくるx,yの値が 0 ~ 1023 なので原点を機体と一致させるために、
中央値を引いてx,yに格納、このx,yを使ってモーターへ出力しています。

#include <Arduino.h>
#include "myBLEController.h"

hw_timer_t *timer = NULL;    // タイマーのポインタ

void onTimer();

// グローバルにインスタンスを用意
MyBLEController myBLE;

#define MR_PWM 4
#define MR_DIR 5
#define ML_PWM 6
#define ML_DIR 7

void setup() {
  Serial.begin(115200);
  // BLE初期化
  myBLE.begin("My BLE Controller");  // 広告するデバイス名

  timer = timerBegin(1000);  // タイマーを1kHzで初期化
  timerAttachInterrupt(timer, &onTimer);  // 割り込み関数を設定
  timerAlarm(timer, 50, true, 0);  // 50msごとに割り込みを発生させる

  pinMode(MR_PWM,OUTPUT);
  pinMode(MR_DIR,OUTPUT);
  pinMode(ML_PWM,OUTPUT);
  pinMode(ML_DIR,OUTPUT);
}

static std::array<std::array<int, 2>, 2> current;

int x = 0;
int y = 0;

void IRAM_ATTR onTimer() {
  // 何かキーが受信されていれば確認
  // static String lastVal;
  current = myBLE.getLastReceived();
  Serial.print("d0:");
  Serial.print(current[0][0]);
  Serial.print(current[0][1]);
  Serial.print(",d1:");
  Serial.print(current[1][0]);
  Serial.println(current[1][1]);

  x = (current[0][0] - 512);
  y = (current[0][1] - 512);
}

float ml_power = 0;
float mr_power = 0;

void loop() {
  analogWrite(ML_PWM, 0);
  analogWrite(MR_PWM, 0);

  ml_power = 255*(-x+y)/1024;
  mr_power = 255*(-x-y)/1024;

  analogWrite(ML_PWM, abs(ml_power));
  analogWrite(MR_PWM, abs(mr_power));

  if(ml_power>0) digitalWrite(ML_DIR,1);
  else digitalWrite(ML_DIR,0);
  if(mr_power>0) digitalWrite(MR_DIR,1);
  else digitalWrite(MR_DIR,0);
  
  Serial.print(ml_power);
  Serial.println(mr_power);

  delay(50);
}

ESP32への書き込み

最初は,"ESP32 familydevice"と認識されるはず.
ツール → ボード → ESP32 → ESP32S3 Dev Module
にボードを変更する.

すると,ツールにオプションが出てくる.これを適切に設定する.
とりあえず下記のように設定すればOK(各設定項目の説明は最後に記す.

書き込み

ESP32に書き込む.ESP32が起動すると,自動でサーバーが立つ.
書き込みに失敗するよくあるパターンとして,ESP32がブートモードになっていない場合がある.
手動ブートモード:BOOTボタンを押しっぱなし → RESET → 指を離す順番で試す。

BLE通信

MicroBlueを起動し,右上のBluetoothマークから,"myBLEcontroller"を選択.
操作画面の"d0"のjoyコン、もしくは十字キーで操作することができます。

動かす

以下は、Arduino IDEの「ツール」メニューで選択できるESP32-S3の設定項目の説明です。

1. USB CDC On Boot: "Enabled"

  • CDC (Communications Device Class)を有効化するかどうか
  • Enabled にすると、ESP32-S3が仮想シリアルポートとして認識される
  • これを有効にすると、USBケーブルでESP32-S3とPC間のシリアル通信が可能になる

2. CPU Frequency: "240MHz (WiFi)"

  • ESP32-S3の動作クロック(CPU速度)
  • 240MHz はESP32-S3の最大クロック速度
  • WiFi と書かれているのは、この設定がWiFi利用時の推奨設定であるため

3. Core Debug Level: "None"

  • デバッグログの出力レベル
  • None にするとデバッグメッセージが表示されない
  • Verbose にすると詳細なデバッグ情報が出る(開発時には便利だが、動作が遅くなる)

4. USB DFU On Boot: "Disabled"

  • DFU(Device Firmware Update)を有効にするかどうか
  • DFUを有効 (Enabled) にすると、ESP32-S3をUSB経由でファームウェア更新できる
  • Disabled にすると通常のUART経由での書き込みのみ可能

5. Erase All Flash Before Sketch Upload: "Disabled"

  • スケッチを書き込む前にフラッシュメモリを全消去するかどうか
  • Enabled にすると、毎回フラッシュメモリが完全消去される(問題が発生したときのリセット用)
  • Disabled にすると、前のデータが部分的に残る(通常はこれでOK)

6. Events Run On: "Core 1"

  • ESP32-S3のどのCPUコアでイベントを処理するか
  • ESP32-S3はデュアルコア (Core 0 & Core 1) を持つ
  • Core 1 は通常、WiFiやBLEの処理に使われる

7. Flash Mode: "QIO 80MHz"

  • フラッシュメモリのアクセスモードと速度
  • QIO (Quad Input/Output) は4本のデータ線を使って高速アクセスするモード
  • 80MHz はフラッシュの動作クロック

8. Flash Size: "4MB (32Mb)"

  • ESP32-S3のフラッシュメモリ容量
  • 4MB(=32メガビット)のストレージが使える
  • より大きな容量のESP32-S3ボードもある(例: 8MB16MB

9. JTAG Adapter: "Disabled"

  • JTAGデバッグを有効化するか
  • Enabled にするとJTAG(ハードウェアデバッグ)が使えるが、通常は Disabled で問題ない

10. Arduino Runs On: "Core 1"

  • Arduinoスケッチが動作するCPUコア
  • Core 1 にすると、WiFiやBLEと同じコアでスケッチが動作する
  • Core 0 に変更すると、WiFiとは別のコアでスケッチが実行される(リアルタイム処理向け)

11. USB Firmware MSC On Boot: "Disabled"

  • ESP32-S3をUSBストレージデバイスとして起動するか
  • Enabled にすると、PCにUSBメモリのように認識される
  • Disabled の場合は通常の動作

12. Partition Scheme: "Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS)"

  • ESP32-S3のフラッシュメモリのパーティション構成
  • APP 1.2MB:プログラム用の領域
  • SPIFFS 1.5MB:SPI Flash File System(データ保存用)

他のオプション:

  • "No OTA (2MB APP/1.5MB SPIFFS)" → OTA(Over-the-Air)アップデートなし、アプリ領域が広い
  • "Minimal SPIFFS (1.9MB APP/190KB SPIFFS)" → アプリの領域を最大化

13. PSRAM: "Disabled"

  • ESP32-S3に追加のPSRAM(Pseudo-SRAM)がある場合に有効化
  • Enabled にすると、大量のメモリが必要な処理(画像処理など)が可能になる
  • Disabled なら内蔵RAMのみ使用

14. Upload Mode: "UART0 / Hardware CDC"

  • プログラムの書き込み方式
  • UART0 → シリアルポート経由で書き込み
  • Hardware CDC → USB経由で書き込み(通常はこっちでOK)

15. Upload Speed: "921600"

  • ESP32-S3へのプログラム書き込み速度(ボーレート)
  • 921600 は高速設定(通常はこれでOK)
  • もし書き込みに失敗する場合は 115200 に変更

16. USB Mode: "Hardware CDC and JTAG"

  • USBの機能設定
  • Hardware CDC → USBシリアル通信を有効化
  • JTAG → ハードウェアデバッグも有効

17. Zigbee Mode: "Disabled"

  • Zigbee通信機能を有効にするか
  • Disabled ならZigbee通信はオフ
  • ESP32-S3の一部のモデルはZigbeeをサポートするが、通常は不要

Discussion