PlatformIOで作成したESP32ファームウェアをESP Web Toolsで書き込む

PlatformIOで作成したESP32ファームウェアをESP Web Toolsで書き込みます。
ESP Web Toolsは、単なる静的なWebページです。利用者は、ブラウザさえ用意すればよく、開発環境等は不要なので、配布に便利です。

もろもろはGitHubに上げておきました。

poruruba/QuickJS_ESP32_IoT_Console

https://github.com/poruruba/QuickJS_ESP32_IoT_Console

ESP Web Toolsに関しては以下が参考になります。

　https://esphome.github.io/esp-web-tools/
　https://github.com/esphome/esp-web-tools/
　[ESP Web Toolsを使用してビルド済バイナリを配布する方法](https://qiita.com/kitazaki/items/ecab46bc66c46b0c916b)

# ファームウェアファイルを作成する

まずは、単純にPlatformIOで、ESP32アプリケーションを作成しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/beee6257-ec00-b40c-9bbb-e002e3e6d5f5.png)

今回は、Boardとして、M5Stick-Cを選びました。FrameworkはArudinoを選びました。
以下、なんでもよいので超適当なアプリです。

```cpp:HelloWorld\src\main.cpp
#include <M5StickC.h>

void setup() {
  // put your setup code here, to run once:
  M5.begin(true, true, true);
  Serial.println("setup finished");
}

void loop() {
  // put your main code here, to run repeatedly:
  M5.update();
  Serial.println("Hello World");
  delay(1000);
}
```

```ini:HelloWorld\platformio.ini
; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:m5stick-c]
platform = espressif32
board = m5stick-c
framework = arduino
monitor_speed = 115200
upload_port = COM4
monitor_port = COM4
lib_deps = m5stack/M5StickC@^0.2.5
```

Buildします。

そうすると、以下のフォルダに、firmware.binとpartitions.binができあがります。

```HelloWorld\.pio\build\m5stick-c\```

ただし、これだけでは足りず、ブートローダなど、アプリに依存しないファイルも必要です。
それは、ESP32のデバイスに依存します。

左側サイドメニューからPlatformIOを選択して、Advancedをクリックします。そうすると、「Verbose Upload」がでてきますので、それをクリックします

そうすると、最後に以下のようなコンソール出力が出てきます。

```
esptool.py --chip esp32 --port "COM4" --baud 1500000 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 XXX\.platformio\packages\framework-arduinoespressif32\tools\sdk\esp32\bin\bootloader_dio_40m.bin 0x8000 XXX\.pio\build\m5stick-c\partitions.bin 0xe000 XXX\.platformio\packages\framework-arduinoespressif32\tools\partitions\boot_app0.bin 0x10000 .pio\build\m5stick-c\firmware.bin
```

これは、ESP32にダウンロードして動作するためのすべてのファイルを、マッピングするアドレス情報とともに指定して作成している様子です。
以下の情報がわかります。

|#|アドレス|ファイル名|
|-|-|-|
|①|0x1000|bootloader_dio_40m.bin|
|②|0x8000|partitions.bin|
|③|0xe000|boot_app0.bin|
|④|0x10000|firmware.bin|

②と④は、さきほどビルドして生成されたものです。①と③は固定ファイルになりますが、ESP32の機種によって異なりますので、間違わないようにします。
とはいっても、ほぼこの情報は変わらないようです。

これで、書き込むファームウェアファイルの準備ができました。

# ESP Web Toolsのmanifest.jsonを作成

こんな感じのJSONファイルを作ります。

```json:manifest.json
{
    "name": "QuickJS_ESP32_Firmware",
    "new_install_prompt_erase": true,
    "builds": [
        {
            "chipFamily": "ESP32",
            "improv": false,
            "parts": [
                {
                    "path": "bootloader_dio_40m.bin",
                    "offset": 4096
                },
                {
                    "path": "partitions.bin",
                    "offset": 32768
                },
                {
                    "path": "boot_app0.bin",
                    "offset": 57344
                },
                {
                    "path": "firmware.bin",
                    "offset": 65536
                }
            ]
        }
    ]
}
```

nameのところは、わかりやすいものにしておきます。
chipFamilyは、ESP32を指定します。（ほかにも、ESP8266、ESP32-C3、ESP32-S2、ESP32-S3が指定できるようですが、試していません。）
あとは、pathのところにファイル名、offsetのところにアドレスを指定します。ちなみに、pathは、manifest.jsonを配置したフォルダからの相対パスを指定します。

# Webページの用意

あとは、HTMLに、以下のように指定するだけです。簡単ですね。

```html:index.html
  <script type="module" src="https://unpkg.com/esp-web-tools@9.2.0/dist/web/install-button.js?module"></script>
  <label>for M5 Stick-C</label>
  <esp-web-install-button manifest="firmwares/m5stick-c/manifest.json"></esp-web-install-button>
```

以下、参考ページです。

https://poruruba.github.io/QuickJS_ESP32_IoT_Console/quickjs_downloader/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/9a517f59-606f-a9a8-84ec-a4517163eb32.png)

今回はついでに、Web Serial APIも付けて、ESP32のUARTも確認できるようなWebページに仕上げておきました。

参考ファームウェアは、以下に示したJavascriptをESP32で動作させることができるアプリです。

https://github.com/poruruba/QuickJS_ESP32_IoT_Device

M5StickCとM5Core2とM5Atom用のファームウェアをすぐダウンロードできるようにしておきました。お持ちのESP32の機種に対応する「CONNECT」ボタンを押してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/50cb0180-8643-ec65-36b8-9ed2ae7e15f7.png)

INSTALL QUICKJS_ESP32_FIRMWARE をクリックします。この名前は、manifest.jsonのnameのところからきています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/965bc861-fe26-e67a-a0cb-8518ca43cfdc.png)

一番最初だけ、Erase deviceのチェックボックスをOnにしてあげましょう。NEXTをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/ffdd9316-4e8e-c0be-7357-2cc817f9bb5d.png)

INSTALLをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/e05c52cf-01fa-939e-6f57-9db4f522ea8e.png)

パーセント表示に代わりますので、100%になるまで待ちます。（参考ファームウェアは結構大きいです。。。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/32e999e7-860e-b559-e530-498d5cebe742.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/9dda254d-3511-1df4-c6db-b6b5418da09b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/4f787900-5657-d36b-90f7-47dc62a314d8.png)

ダウンロード完了です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/e30ac0f3-5397-dbd1-ace1-671442d86f1d.png)

終わったので、とりあえず、Webページをリロードしてください。(UARTをつかんだままなので)

# 参考ファームウェアを動かしてみる

参考ファームウェアは、一番最初に起動したとき、SPIFFSがマウントされていない場合は、マウント処理を行うので、少し時間が必要です。
起動した後は、シリアルコンソールからWiFiのSSIDとパスワードを聞かれるので、TeraTermなどを使って接続して入力します。入力すると、WiFiに接続して、割り当てられたIPアドレスがコンソールに出力されます。
SPIFFSマウントとWiFiパスワード入力は一度のみで大丈夫です。

参考ファームウェアを触って動かしてみるページも用意しました。

https://poruruba.github.io/QuickJS_ESP32_IoT_Console/quickjs_console/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/ddcf5c96-bdea-e247-284a-a56ee0825aab.png)

右上の、base_urlに、ESP32のIPアドレスを入力します。http://[ESP32のIPアドレス] のようにします。
実は、本ページはHTTPSですが、ESP32はHTTPです。ですので、このままだと、Mixed Contentsとなりエラーとなります。間に、リバースプロキシを入れてHTTPSとHTTPを仲介するか、Chromeの設定の「安全でないコンテンツ」を許可するに変更します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/06a61687-a89a-8d74-c741-b91085418ab9.png)

デバイス操作タブの、下の方にある「IpAddress & MacAddress」ボタンを押すと、ESP32に接続してIPアドレスとMACアドレスを取得して表示できるのがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/f98e4fc4-bade-b29d-5f10-02e56709aaf6.png)

以上