2021/12/17(金)ESP32いじりメモ

備忘録。随時加筆。

開発ツール類の違い

  • ESP-IDF
    • コンソールベースの公式開発環境。
    • 「Serial」「SPIFFS」などのArudinoフレームワークを含まない
    • sdkconfigにより、SDKのコンパイル条件を選択できる
  • arduino-esp32
    • Arudino IDEで使用するための、公式開発環境パッケージ。
    • 「Serial」「SPIFFS」などのArudinoフレームワークを含む
    • コンパイル済SDKを含む。
    • 導入が簡単。
  • platform-espressif32
    • VScodeの拡張機能PlatformIOで arduino-esp32 を使えるようにした環境。
    • 環境構築がやや分かりにくいが、コード補完等が充実して使いやすい。

執筆時点で、SDK最新リリース版が「ESP-IDF Ver4.4」です。PlatformIOのほうが圧倒的に使いやすいものの、SDKが古い(ESP-IDF Ver3.3.5)という問題があります。

SDKの違いやVersion確認方法

ESP-IDF公式マニュアルでバージョンを選択することで、APIの違いを確認することができます。

SDK(ESP-IDF)のVersionは「esp_idf_version.h」で定義されており、以下のようにすることで、Versionによって条件コンパイルをすることができます。

#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0) 
	// Version 4.0以降
#else
	// Version 4.0未満
#endif

ESP32のSDKはこのソースを使用すると、自分でビルドできます。

Bluetoothのスキャンon/off

Arudinoフレームワーク(BluetoothSerial等)には、SCANをオン/オフする方法がないため、Bluetoothをbegin後により下位のAPIを呼び出します。

ESP-IDF Ver4.0以降ではこうなります。

#include <esp_gap_bt_api.h>

// スキャンon
esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE)
// スキャンoff
esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_NON_DISCOVERABLE)

ESP-IDF Ver3.xにも対応する場合には以下のようになります。

#include <esp_gap_bt_api.h>

#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0) 
#   define _esp_bt_discovery_mode()     esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE)
#   define _esp_bt_non_discovery_mode() esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_NON_DISCOVERABLE)
#else
#   define _esp_bt_discovery_mode()     esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE)
#   define _esp_bt_non_discovery_mode() esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE)
#endif

// スキャンon
_esp_bt_discovery_mode();
// スキャンoff
_esp_bt_non_discovery_mode();

Bluetooth Serial(SPP = Serial Port Profile)

接続するとWindowsから2つのCOMポートが見えるものの、通信できるのは片方のみです。

これはESP32の問題ではなくWindowsの仕様であり、"outgoing"ポートと"incoming" ポートとなっています。Bluetoothデバイス(クライアント)側からの接続要求に答えるのが"incoming"ポート。こちらから接続するときは"outgoing"ポートとなります。

どちらがどちらに割り当てられているかは、Windowsの「設定」→「Bluetoothとその他のデバイス」→「その他のBluetoothオプション」→「COMポート」から確認できます。

認証関係 SSP

SSPを使いたい場合は以下のようにします。

BluetoothSerial SerialBT;
void setup() {
	SerialBT.enableSSP();
	SerialBT.onConfirmRequest(btConfirmRequestCallback);
	SerialBT.onAuthComplete  (btAuthCompleteCallback);
	SerialBT.begin("ESP32-TEST");
	SerialBT.setPin("5555");
}

btConfirmRequestCallback(int num) が呼ばれた後、「btSerial.confirmReply(true)」すると、ペアリングに成功します(btConfirmRequestCallback内でなくて構わない)。 falseにするとペアリングに失敗します。機器側の操作により、true/falseを変更することにより、ペアリングの可否を変更できます。

「num」の数字は、ペアリングする機器側が生成した確認用の乱数(機器側の画面に表示されている)で、ペアリングの際に機器側が送信してきます。

参考文献: SerialToSerialBT_SSP_pairing.ino

SPIFFS

内蔵SPIフラッシュ4MBのうち、1.5MB(デフォルト値)を使用したフラッシュファイルシステムがあります。*1

*1 : ちなみにプログラム領域は1.3MBぐらい。

パーティションの変更

ESP32の標準では、パーティションが以下のようになっています。

# Name,   Type, SubType, Offset,  Size, Flags
nvs,      data, nvs,     0x9000,  0x5000,
otadata,  data, ota,     0xe000,  0x2000,
app0,     app,  ota_0,   0x10000, 0x140000,
app1,     app,  ota_1,   0x150000,0x140000,
spiffs,   data, spiffs,  0x290000,0x170000,

開発中にアプリ領域が足りなくなってしまったので、SPIFFSを448KBに縮小し、アプリ領域を1.7MBに拡張しました。

# Name,   Type, SubType, Offset,  Size, Flags
nvs,      data, nvs,     0x9000,  0x5000,
otadata,  data, ota,     0xe000,  0x2000,
app0,     app,  ota_0,   0x10000, 0x1C0000,
app1,     app,  ota_1,   0x1D0000,0x1C0000,
spiffs,   data, spiffs,  0x390000,0x70000,

このファイルは custom_part.csv などとして保存します。

  • PlatformIOでは、このファイルを platform.ini と同じフォルダに置き、iniファイル中で「board_build.partitions = partitions.csv」などとして設定します。
  • Arudino IDEでは、このファイルを「C:\Users\XXXX\AppData\Local\Arduino15\packages\esp32\hardware\esp32\(Version)\tools\partitions」に置き、「C:\Users\XXXX\AppData\Local\Arduino15\packages\esp32\hardware\esp32\(Version)\board.txt」を編集した上で、GUI上で選択する必要があります。

SPIFFSをほとんど使わないのならば、既存の「min_spiffs.csv」を使うほうが楽です。

# Name,   Type, SubType, Offset,  Size, Flags
nvs,      data, nvs,     0x9000,  0x5000,
otadata,  data, ota,     0xe000,  0x2000,
app0,     app,  ota_0,   0x10000, 0x1E0000,
app1,     app,  ota_1,   0x1F0000,0x1E0000,
spiffs,   data, spiffs,  0x3D0000,0x30000,

※プログラム領域: 1.9MB, SPIFFS: 192KB

シリアル経由の書き込みを安定させる

ESP32-DevKitCの回路図にあるとおり、RTS/DTR(+トランジスタ2個)を使って、ESP32のリセットpinとboot pinを操作します。これにより、手動でリセットしなくても自動的に書き込みモードに移行できるのですが、USBシリアルのタイミング(RTS/DTRの操作仕様)との兼ね合いでこの動作の成功率が高くありません。

解決法としては、ESP32の2pin(3.3V)と3pin(EN)の間に1uFのコンデンサを接続します。こうすることで、タイミングがうまく噛み合い書き込み動作が安定します。

書き込み速度を3Mbpsに

  • Arduino IDEの場合は「C:\Users\XXXX\AppData\Local\Arduino15\packages\esp32\hardware\esp32\(Version)\board.txt」を編集。
  • VSCode ならば platformio.ini に「upload_speed = 3000000」を追加。

platform I/OでSPI Flashの速度を80MHzに設定

標準ではなぜか「40MHz」になっており、この速度が異なるとOTAアップデートに失敗する(見かけ成功するがSPI処理で止まる)ので、これを80MHz設定しておきます。

  • platform.iniに「board_build.f_flash = 80000000L」を設定。

参考文献

関連記事