July 8, 2024 | 03:08

ESP32

ESP32 を使用していて個人的に気になったことやハマったポイントのメモを残します

開発環境

Arduino IDE

最初期はお手軽。しかし複数プロジェクトを管理できない、純粋な C++ ではないので特有の知識が必要と書き捨て以上のプロジェクトではおすすめできない

PlatformIO

おすすめ。Arduino IDE からの移行も簡単でライブラリも同じものが使える

String vs std::string

String は Arduino IDE で使用されるクラスであり、C++ 標準ライブラリの std::string とは別物。いずれもメモリの動的確保を行うため、メモリの断片化が発生する。 String は最大10文字までは SSO (Small String Optimization) が行われるため、メモリの動的確保は行われない。std::string の SSO は実装依存であり、PlatformIO で使用される gcc では 15文字まで SSO が行われる。

ESP32 の環境では String を使用するメリットは薄いので、既存ライブラリで String が使用されている場合意外では Arduino環境以外との互換性を考えて std::string を使用するで良いと思われる。

Flash Partition Table

ESP32 では Flash Partition Table によって、フラッシュメモリの領域を論理的に分割することができる。

設定は platform.ini に以下のように記述する

board_build.partitions = default_16MB.csv

default.csv (4MB Flash)は以下のようになっている

Name Type SubType Offset Size Size (KB)
nvs data nvs 0x9000 0x5000 20KB
otadata data ota 0xe000 0x2000 8KB
app0 app ota_0 0x10000 0x140000 1280KB
app1 app ota_1 0x150000 0x140000 1280KB
spiffs data spiffs 0x290000 0x160000 1408KB
coredump data coredump 0x3F0000 0x10000 64KB

default_16MB.csv は以下のようになっている

Name Type SubType Offset Size Size (KB)
nvs data nvs 0x9000 0x5000 20KB
otadata data ota 0xe000 0x2000 8KB
app0 app ota_0 0x10000 0x640000 6400KB
app1 app ota_1 0x650000 0x640000 6400KB
spiffs data spiffs 0xc90000 0x360000 3456KB
coredump data coredump 0xFF0000 0x10000 64KB

用途

  • nvs (Non-Volatile Storage)
    • 非揮発性の設定やデータを保存するための領域。Wi-Fiの設定やアプリケーションの設定値など、再起動後も保持する必要があるデータを書く領域
  • otadata (Over-The-Air (OTA) Data)
    • ファームウェアのアップデートに関する情報を保持する領域。OTAプロセス中にどのパーティションがアクティブかや、アップデートの状態などが記録
  • app0 (Application 0)
    • アプリケーションのファームウェア本体を格納する領域。OTAアップデートを使用する場合、2つのアプリケーション領域が交互に使われる(app0とapp1)
  • app1 (Application 1)
    • 2つ目のアプリケーション領域で、OTAアップデート時に新しいファームウェアバージョンを格納する。アップデート成功後、この領域が新たなアクティブなファームウェアとして機能する。
  • spiffs (SPI Flash File System)
    • ファイルシステムを提供する。アプリケーションによっては、追加のデータや設定ファイルをこの領域に保存する
  • coredump (Core Dump)
    • システムがクラッシュした際に、コアダンプ(メモリのダンプ)を保存する領域

内蔵ファイルシステム (SPIFFS/LittleFS)

現在は LittleFS の方が良いらしい。

パーティションは spiffs のままでも動くが PlatformIO で LittleFS を使用する場合は、以下のように設定する

board_build.filesystem = littlefs

data フォルダにファイルを配置することで、ビルド時に LittleFS に書き込まれる。便利。

パーティションを littlefs に変更した場合は上記の設定は不要なはず。

ライブラリ

ArduinoJson

JSON のシリアライズ、デシリアライズを行うライブラリ。 filter を使用すると、省メモリで特定のキーのみを取り出すことができる。 StaticJsonDocument はスタックに確保され、DynamicJsonDocument はヒープに確保される。

デシリアライズのサンプル

  StaticJsonDocument<200> filter;
  filter["result"][0]["flag"] = true;

  StaticJsonDocument<2048> doc;
  deserializeJson(doc, str, DeserializationOption::Filter(filter));

  for (auto result : doc["result"].as<JsonArray>()) {
    Serial.println(result["flag"].as<bool>());
  }

シリアライズのサンプル

  const int capacity = JSON_OBJECT_SIZE(256);   // 256 はオブジェクトの数
  StaticJsonDocument<capacity> doc = {};

  doc["result"][0]["flag"] = true;
  doc["result"][1]["flag"] = false;
  doc["result"][2]["flag"] = true;

  char buffer[4096];
  serializeJson(doc, buffer, sizeof(buffer));
  Serial.println(buffer);

シリーズ比較表

誤りが含まれている可能性があります。ご了承ください。

特徴 ESP32 ESP32-S2 ESP32-S3 ESP32-C3 ESP32-C2 (ESP8684) ESP32-C6 ESP32-H2
CPU Tensilica Xtensa LX6 Xtensa LX7 Xtensa LX7 RISC-V 32 bit RISC-V 32 bit RISC-V 32 bit RISC-V 32 bit
CPUコア数 2 1 2 1 1 1 1
Max CPU Freq. 240 MHz 240 MHz 240 MHz 160 MHz 160 MHz HP: 160 MHz, LP: 20 MHz 96 MHz
RAM 520 KB 320 KB 512 KB 400 KB 272 KB 512 KB 320 KB
In-Package Flash 最大16 MB 2 or 4MB 0 or 4 or 8MB 0MB or 4MB 2MB or 4MB 0MB or 4MB 2 MB or 4 MB
Off-Package Memory Max 16MB Max 1GB Max 1GB Max 16 MB なし Max 16 MB なし
In-Package PSRAM なし 0 or 2MB 2MB (Quad SPI), 8 or 16MB (Octal SPI) なし なし なし  なし
Wi-Fi Wi-Fi 4 (802.11 b/g/n) Wi-Fi 4 (802.11 b/g/n) Wi-Fi 4 (802.11 b/g/n) Wi-Fi 4 (802.11 b/g/n) Wi-Fi 4 (802.11 b/g/n) Wi-Fi 6 (802.11 b/g/n/ax) なし
Bluetooth v4.2 BR/EDR および BLE なし Bluetooth 5 LE Bluetooth 5 LE Bluetooth 5 LE Bluetooth 5 LE Bluetooth 5 LE
その他の無線プロトコル なし なし なし なし なし IEEE 802.15.4 (Thread/Zigbee) IEEE 802.15.4 (Thread/Zigbee)
GPIOピン 最大34 最大43 最大45 最大22 最大14 30 (QFN40) or 22 (QFN32) 19
セキュリティ機能 セキュアブート, フラッシュ暗号化 セキュアブート, フラッシュ暗号化 セキュアブート, フラッシュ暗号化 セキュアブート, フラッシュ暗号化 セキュアブート, フラッシュ暗号化 セキュアブート, フラッシュ暗号化, 信頼実行環境 (TEE), HMAC セキュアブート, フラッシュ暗号化, 信頼実行環境 (TEE), ECDSA, HMAC
USBサポート なし あり あり なし なし なし なし
  • PSRAM: Pseudo SRAM (疑似SRAM)

個人的なおすすめ

  • ESP32 (Flash 4MB)
    • 低価格
    • 大量に出回っている
  • ESP32-S3 (N16R8: Flash 16MB, PSRAM 8MB など)
    • 性能が高い
    • PSRAM 内蔵でメモリが潤沢
    • USB サポート

デバッグ

printf デバッグ

Serial.begin() で初期化したシリアルポートを使用して printf デバッグを行うことができる。

Serial.begin(3000000);
printf("Hello, World!\n");

Serial Monitor を開くと表示される。Monitor を止めないと Upload できないので注意

Serial Monitor

ESP32-S3 でのデバッガの利用

ESP32-S3 では PlatformIO で簡単にデバッグができる。ただ、動作は遅く、不安定なような…

Windows でのドライバの変更

Windows の場合は Zadig を使ってドライバを WinUSB に変更する必要がある。

Step1: Options -> List All Devices を選択

Alt text

Step2: USB JTAG/serial debug unit (interface 0) を選択

USB Serial (CDC) を選択して Upgrade Driver or Downgrade Driver をクリック Alt text

Step3: USB JTAG/serial debug unit (interface 2) を選択

WinUSB を選択して Replace Driver をクリック

Alt text

デバイスマネージャーの表記が USB JTAG/serial debug unit (interface 0) (COMx) のようになっていれば OK Alt text

esptool

接続しているモジュールのスペック(種類・Flash容量)を調べられる

ESP32, 4MB Flash

> esptool.exe --port COMx flash_id
esptool.py v4.5.1
Serial port COMx
Connecting....
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting.....
Detecting chip type... ESP32
Chip is ESP32-D0WD-V3 (revision v3.1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: XX:XX:XX:XX:XX:XX
Uploading stub...
Running stub...
Stub running...
Manufacturer: 5e
Device: 4016
Detected flash size: 4MB
Hard resetting via RTS pin...

ESP32-S3, 16MB Flash, PSRAM

> esptool.exe --port COMx flash_id
esptool.py v4.5.1
Serial port COMx
Connecting...
Detecting chip type... ESP32-S3
Chip is ESP32-S3 (revision v0.2)
Features: WiFi, BLE
Crystal is 40MHz
MAC: XX:XX:XX:XX:XX:XX
Uploading stub...
Running stub...
Stub running...
Manufacturer: 5e
Device: 4018
Detected flash size: 16MB
Flash type set in eFuse: quad (4 data lines)
Hard resetting via RTS pin...

PSRAM の容量は esptool では調べられないらしい