ESP-IDFを使ってみる

ESP32-S2開発ボード

2019年にESP32-S2がリリースされました。
今回3種類のESP32-S2開発ボードを入手しました。
いずれもLilyGoブランドの製品です。

左から
ESP32-S2-WROOM
ESP32-S2
ESP32-S2+1.14 Inch LCD Display




ESP32開発ボードと比べ、ボードの高さが1ピン分小さくなっているので、ブレッドボードで使うことができます。




ESP32-S2 と ESP32-S2+1.14 Inch LCD Display にはマイクロSDカードスロットが実装されています。
また、バッテリーからも給電可能になっていて、写真右下のスライドSWで給電ポートを切り替えます。
スライドSW=ON:USBポートから給電
スライドSW=OFF:右側の白いコネクターから給電


こちら
にLilyGo公式のサンプルコードが公開されています。
FAT32でフォーマットした4GのSDカードを付けて、#define HAS_SDCARDを有効にしてビルドしてみました。
きちんとSDカードを認識しています。
ソースを見るとSDカードリーダーとの接続はSPIインタフェースで、GPIO14がSDカードリーダーのVCCに接続されている様で、
ここをONにして、SDカードリーダーに通電する必要がありま す。


ログをよく見るとワーニングが表示されています。


このワーニングはmenuconfigで以下の項目を変更することで回避することができます。




Ai-ThinkerのESP-12H搭載の開発ボードを入手しました。
ESP-12HはESP32-S2FのSoCを搭載したモジュールです。
ESP32-S2にはFlashが内蔵されていませんが、ESP32-S2Fには2Mあるいは4MのFlashが内蔵されています。
フルカラーLEDが付いていて、RGBがIO20、IO9、IO19に繋がっています。


ESP32-S2のSoCは30本以上のGPIOを使うことができますが、このボードはTXD、RXDを除いて17本しか使うことができません。


AmicaブランドのNodeMCU(ESP8266)と同じ形状で、Resetボタンとブートモード切替のボタンの位置も同じです。
明らかにESP8266の置き換えを狙った製品です。


この様なファームが最初から書き込まれていました。


ファームを変更してspi_flash_get_chip_size()を実行してみました。
2MBのFlashと言う事は分かりましたので、ESP32-S2FH2のSoCが使われ ていることが分かりました。
2021年時点でESP32-S2FにはESP32-S2FH2(2M)/ESP32-S2FH4(4M)/ESP32- S2FN4R2(4M+PSRAM)のバリエーションが存在します。


ESP-12HはESP-12と同じフォームファクターのモジュールです。
ESP-12用のピッチ変換基盤が使えます。
ESP-12に比べてハウジングサイズが少し大きくなっています。


フォームファクターは同じですが、ピンアサインは違っています。


ピンアサインを比べるとこの様になります。
3V3、EN、GND、TXD、RXDの位置だけは同じです。
下側のピンも全てGPIOとして使えます。


データシートによるとIO46をPullDown、IO0をPullDownにした状態でリセットすると書き込みモードになりますが、
IO46は外に出ていないので、IO0をPullDownした状態でリセットすると書き込みモードになります。
IO0をPullUPした状態でリセットすると、IO46の状態に関係なくSPI Flashから起動します。
IO0はSoC内部でPullUpされているので、オープンにするとPullUpとなります。
ENはPullUpされていないので、リセット回路を構成する際にはPullUpしておく必要があります。
Pin Default SPI boot mode Download start mode
IO46 PullDown (ANY) PullDown
IO0 PullUp PullUp PullDown

こちらで紹介しているESP32-C3-12Fでは、GPIO9をSPI boot modeとDownload start modeの切り替えに使用します。
ESP-12Hでは、GPIO0をSPI boot modeとDownload start modeの切り替えに使用します。
どちらもピンの位置が同じ(右側の上から5番目)です。
起動に必要なGND、3.3V、ENも同じ位置なので、書き込みに時にはESP32-C3-12FとESP-12Hで同じ基盤が使えます。
もちろんGPIOのアサインが違うので、実行時の互換性は有りません。

aitendoのピッチ変換基盤にマウントしてみました。
右側は同じフォームファクターのESP-12です。
ESP-12には有るオンボードLEDは、ESP-C3-F12には有りません。


ピッチ変換基盤を使って、必要な抵抗などをブレッドボードパターンのユニバーサル基盤に組むとこのようになります。
No10は3V3とGNDです。
上のNo15から伸びているジャンパー線はENです。
下のNo11から伸びているジャンパー線は、ESP32-C3-12Fの為のIO8のPullUpです。
ESP-12Hでは不要な抵抗です。
下のNo13から伸びているジャンパー線はSPI boot modeとDownload start modeの切り替えです。
この位置がESP-12HとESP32-C3-12Fで同じなので、ESP-12HとESP32-C3-12Fで共通した回路にすることができま す。
1本線の抵抗が沢山有りますが、ジャンパー抵抗(0Ω抵抗)で、短い距離の時はこれでパターンを跨いでいます。


GPIOがフルに使えるESP-12Kというモジュールが有りますが、ESP-WROOM-32が左右14ピンに対し、
ESP-12Kは左右16ピンとなっていて、このピン数に対応したピッチ変換基盤が見つかりません。



ESP32 と ESP32-S2 の違いはこ ちらに良くまとまっています。
EPS32-S2はESP32からいろいろな機能が削られていて、RAMやROMも小さくなっていますが、以下の機能が追加されています。
  • Wi-Fi ToF(Wi-Fi Round Trip Time)
  • USB OTG
  • LCD Interface
  • Camera Interface
  • Temperature Sensor

  • ESP32には有った入力専用GPIOは無くなっています。
    全てのGPIOが入出力として使うことができます。

    ESP32-S2にはこ ちらの JPEGライブラ リが含まれていません。
    espressifに問合せしたら、ESP32-S2のROMが小さいから含めることが出来ないとの回答でした。
    但し、ESP-IDF Ver5からはこ ちらのコンポーネントが使えます。

    esp-idfには多数のサンプルコードが付属しています。
    ほとんどのサンプルコードがS2/S3のどちらでも動きますが、こ のサンプルだけはS2だけで動くサンプルコードです。
    $ grep -rn  "Supported Targets" * | grep ESP32-S2 | grep -v "ESP32 "
    peripherals/rmt/musical_buzzer/README.md:1:| Supported Targets | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
    peripherals/dedicated_gpio/soft_uart/README.md:1:| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
    peripherals/dedicated_gpio/soft_i2c/README.md:1:| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
    peripherals/gpio/matrix_keyboard/README.md:1:| Supported Targets | ESP32-S2 |
    peripherals/usb/device/tusb_msc/README.md:1:| Supported Targets | ESP32-P4 | ESP32-S2 | ESP32-S3 |
    peripherals/usb/device/tusb_ncm/README.md:1:| Supported Targets | ESP32-S2 | ESP32-S3 |
    peripherals/usb/device/tusb_hid/README.md:1:| Supported Targets | ESP32-P4 | ESP32-S2 | ESP32-S3 |
    peripherals/usb/device/tusb_composite_msc_serialdevice/README.md:1:| Supported Targets | ESP32-P4 | ESP32-S2 | ESP32-S3 |
    peripherals/usb/device/tusb_serial_device/README.md:1:| Supported Targets | ESP32-P4 | ESP32-S2 | ESP32-S3 |
    peripherals/usb/device/tusb_serial_device/managed_components/espressif__esp_tinyusb/test_app/README.md:1:| Supported Targets | ESP32-S2 | ESP32-S3 |
    peripherals/usb/device/tusb_console/README.md:1:| Supported Targets | ESP32-P4 | ESP32-S2 | ESP32-S3 |
    peripherals/usb/device/tusb_midi/README.md:1:| Supported Targets | ESP32-P4 | ESP32-S2 | ESP32-S3 |
    peripherals/usb/host/usb_host_lib/README.md:1:| Supported Targets | ESP32-P4 | ESP32-S2 | ESP32-S3 |
    peripherals/usb/host/msc/README.md:1:| Supported Targets | ESP32-P4 | ESP32-S2 | ESP32-S3 |
    peripherals/usb/host/cdc/cdc_acm_vcp/README.md:1:| Supported Targets | ESP32-P4 | ESP32-S2 | ESP32-S3 |
    peripherals/usb/host/cdc/cdc_acm_host/README.md:1:| Supported Targets | ESP32-P4 | ESP32-S2 | ESP32-S3 |
    peripherals/usb/host/hid/README.md:1:| Supported Targets | ESP32-P4 | ESP32-S2 | ESP32-S3 |
    peripherals/usb/host/hid/managed_components/espressif__usb_host_hid/test_app/README.md:1:| Supported Targets | ESP32-S2 | ESP32-S3 |
    peripherals/usb/host/uvc/README.md:1:| Supported Targets | ESP32-P4 | ESP32-S2 | ESP32-S3 |
    peripherals/touch_sensor/touch_element/touch_element_waterproof/README.md:1:| Supported Targets | ESP32-S2 | ESP32-S3 |
    peripherals/touch_sensor/touch_element/touch_elements_combination/README.md:1:| Supported Targets | ESP32-S2 | ESP32-S3 |
    peripherals/touch_sensor/touch_element/touch_matrix/README.md:1:| Supported Targets | ESP32-S2 | ESP32-S3 |
    peripherals/touch_sensor/touch_element/touch_slider/README.md:1:| Supported Targets | ESP32-S2 | ESP32-S3 |
    peripherals/touch_sensor/touch_element/touch_button/README.md:1:| Supported Targets | ESP32-S2 | ESP32-S3 |
    peripherals/touch_sensor/touch_sensor_v2/touch_pad_read/README.md:1:| Supported Targets | ESP32-S2 | ESP32-S3 |
    peripherals/touch_sensor/touch_sensor_v2/touch_pad_interrupt/README.md:1:| Supported Targets | ESP32-S2 | ESP32-S3 |
    peripherals/temperature_sensor/temp_sensor/README.md:1:| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
    peripherals/spi_slave_hd/segment_mode/seg_slave/README.md:1:| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
    peripherals/spi_slave_hd/segment_mode/seg_master/README.md:1:| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
    peripherals/spi_slave_hd/append_mode/slave/README.md:1:| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
    peripherals/spi_slave_hd/append_mode/master/README.md:1:| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
    protocols/mqtt/ssl_ds/README.md:1:| Supported Targets | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
    security/hmac_soft_jtag/README.md:1:| Supported Targets | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
    security/nvs_encryption_hmac/README.md:1:| Supported Targets | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
    system/ulp/ulp_riscv/gpio_interrupt/README.md:1:| Supported Targets | ESP32-S2 | ESP32-S3 |
    system/ulp/ulp_riscv/interrupts/README.md:1:| Supported Targets | ESP32-S2 | ESP32-S3 |
    system/ulp/ulp_riscv/gpio/README.md:1:| Supported Targets | ESP32-S2 | ESP32-S3 |
    system/ulp/ulp_riscv/i2c/README.md:1:| Supported Targets | ESP32-S2 | ESP32-S3 |
    system/ulp/ulp_riscv/adc/README.md:1:| Supported Targets | ESP32-S2 | ESP32-S3 |
    system/ulp/ulp_riscv/uart_print/README.md:1:| Supported Targets | ESP32-S2 | ESP32-S3 |
    system/ulp/ulp_riscv/ds18b20_onewire/README.md:1:| Supported Targets | ESP32-S2 |
    system/ulp/ulp_riscv/touch/README.md:1:| Supported Targets | ESP32-S2 | ESP32-S3 |
    system/console/advanced_usb_cdc/README.md:1:| Supported Targets | ESP32-S2 | ESP32-S3 |
    system/xip_from_psram/README.md:1:| Supported Targets | ESP32-S2 | ESP32-S3 |
    wifi/ftm/README.md:1:| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |



    2022年1月にesp-idf v5が公開されました。
    このバージョンからUSB HOST機能がサポートされました。
    こ ちらにサンプルが公開されています。
    CDC-ACMを使った通信と、USBメモリー(Flash Drive)アクセスのサンプルが公開されていますが、
    USBには様々なプロトコルが有るので、使いこなすには時間がかかりそうです。



    こちらの コー ドで、真面目にベンチマークを計ってみました。
    FPUが無いので、ESP32よりも浮動小数点演算能力は低いです。

    O2オプティマイズを有効にすると、整数演算能力も少し差が付きます。
    ESP32ではO2オプティマイズを有効にすると、zero-overhead loopsが有効になりますが、
    ESP32-S2にはFPUに加え、zero-overhead loopsの機能も有りません。



    こちら
    にESP32-S2のTemperature Sensorのサンプルコードが公開されています。
    3台の開発ボードでビルドしてみました。
    室温23.8℃の環境で以下の様になりました。
    測定レンジはいずれも-10度から80度で誤差は1度以下のはずですが、個体差が大きいです。









    AliExpressでESP32 S2-Miniが投げ売りされています。
    $1.49+送料で入手しました。
    5mm方眼の上なのでボードのサイズが分かると思います。




    ボード上にタイプCのUSBコネクターが実装されていますが、USB-TTL変換チップが実装されていません。
    不思議に思っていましたが、こ ちらにSchematicが公開されていました。
    USBポートのD-とD+はGPIO19/20に繋がっています。
    チップのUSB-OTG機能を使っているので、単にUSBケーブルでホストと繋いでもUSBデバイスとして認識されません。
    こ ちらにArduino環境で使うための手順が公開されています。
    まず、Button0を押した状態でButtonRSTを押し、ButtonRST、Button0の順に離します。
    これで、デバイスがDFUモードに入り、USBデバイス(/dev/ttyACM0)が出現し、ファームを書き込みすることができます。
    Button0を押さない状態で、ButtonRSTを押すと単純なリセット動作となり、USBデバイスが消滅します。
    つまり、USBは書き込みには使えますが、STDOUTとしては使えません。
    ESP32-S2では、GPIO43/44がU0TXD/U0RXDですが、このGPIOはピンに出ていません。
    つまり、このままではシリアルモニターによるロギングを行うことが出来ないトホホなボードです。

    そこで、menuconfigでChannel for console outputをUSB CDCに変更し、再度ファームをアップロードします。


    ファームのアップロードが終わると、以下の表示となります。


    ここでButtonRSTを押します。これが肝です。
    これでUSB CDCが有効になっているファームが動き始めます。
    これ以降、Button0もButtonRSTも押さずに、ファームの書き込みとモニターができるようになります。

    メーカの商品ページによるとSoCは「ESP32-S2FN4R2」、つまりEmbedded Flashが4MB、PSRAMが2MBのモデルです。
    PSRAMを有効にしてheap_caps_get_free_size(MALLOC_CAP_SPIRAM)を表示してみました。
    Flashについてはembeddedではなく、「chip ID=0x204016」のSPI Flashが使われていると表示されますが、基板上には明らかにSPI Flashは実装されていません。
    このchip IDはXM25QH32Bチップであることが分かっています。
    PSRAMについては、間違いなく2MBのPSRAMを認識しました。
    ESP32S2はRAMが小さいので、大きな領域を確保することができませんが、PSRAMを有効にすると、一気にRAMが大きくなります。
    I (515) MAIN: embedded=0
    I (515) MAIN: external flash
    I (515) MAIN: chip ID=0x204016
    I (515) MAIN: flash_capacity=0x16
    I (515) MAIN: external 4 Mbytes flash
    I (515) MAIN: PSRAM size: 2097152 bytes 2 Mbytes
    I (515) MAIN: MALLOC_CAP_SPIRAM: 2094724 bytes
    I (515) MAIN: Free heap size: 2306020

    ちなみにこちらがPSRAMを持っていないESP32S2の表示です。
    Free heap sizeが1桁近く違います。
    I (314) MAIN: embedded=0
    I (314) MAIN: external flash
    I (314) MAIN: chip ID=0x204016
    I (324) MAIN: flash_capacity=0x16
    I (324) MAIN: external 4 Mbytes flash
    I (324) MAIN: PSRAM size: 0 bytes 0 Mbytes
    I (334) MAIN: MALLOC_CAP_SPIRAM: 0 bytes
    I (334) MAIN: Free heap size: 249240

    2MのPSRAM付のESP32S2が$1.49と言うのは、お買い得かもし れませ ん。
    結局5個、買ってしまいました。
    なお、AliExpressで購入するときは、一気に4個買うよりも、2個を2回に分けて買う方が送料が安くなる場合が有ります。
    今回購入したセーラーの場合、2個だと送料が$1.92でしたが、3個以上になると、一気に$5.02に跳ね上がりました。


    続く....