ESP32でWebデータをFlashから読み出し

2023年9月4日技術開発ESP32

概要

ESP-WROOM-32のFlashにはFilesystem領域と呼ばれるスペースが確保されており、そこにファイルを保存することが出来ます。
今回はsoftAPモードでWebサーバーを起動し、Flashから読み込んだWebデータをブラウザに表示させます。

また、今回は標準のライブラリではなく「ESPAsyncWebServer」ライブラリでWebサーバーを構築しています。
これはESP32で非同期なサーバーを実現できるライブラリです。非同期なのでプログラム上では常にclientを監視しなくてもよくなり、loop内でLチカ等の他のプログラムを動かしながらサーバーも動かせます。

実行環境

MCU:ESP32-Devkit-C(ESP-WROOM-32)
IDE:PlatformIO(Core 6.1.7·Home 3.4.4) ※Arduinoでも可(なはず)

参考サイト

ライブラリのインストール

まずWebサーバー機能を実装するのに使うライブラリを「ESPAsyncWebServer」をインストールします。

次にESPAsyncWebServerの動作に必要なライブラリ「AsyncTCP」をインストールします。

フラッシュ書き込み用ツールのインストール(PlatformIOでは不要)

画面表示に必要なhtmlファイルやCSSファイルはESP32内蔵Flashに書き込むため、書き込みツール「ESP32FS」が必要になります。

まずESP32FSをGithubのリリースページからダウンロードします。

ダウンロードしたものを解凍し、Arduinoフォルダのtoolsフォルダに保存します。
例)C:\Users\USER\Documents\Arduino\tools\ESP32FS
Arduino IDE を起動し、「ツール」メニューに「ESP32 Sketch Data Upload」という項目が作られていればインストール完了です。

サンプルコード

ESP32をsoftAPモードに設定し、Flashに保存された「index.html」と「style.css」をポート80で公開するプログラムです。
プロジェクトの作成と書き込みの手順は省略します。

#include <WiFi.h>
#include "ESPAsyncWebServer.h"
#include "SPIFFS.h"

const char ssid[] = "ESP32AP-TEST";
const char pass[] = "12345678";         // パスワードは8文字以上にする
const IPAddress ip(192,168,123,45);     // ESP32のIPアドレス
const IPAddress subnet(255,255,255,0);  // サブネットマスク
AsyncWebServer server(80);              // ポート設定

void setup()
{
  Serial.begin(115200);

  // SPIFFSのセットアップ
  if(!SPIFFS.begin(true)){
    Serial.println("An Error has occurred while mounting SPIFFS");
    return;
  }
  
  WiFi.softAP(ssid, pass);           // SSIDとパスの設定
  delay(100);                        // このdelayを入れないと失敗する場合がある
  WiFi.softAPConfig(ip, ip, subnet); // IPアドレス、ゲートウェイ、サブネットマスクの設定
  
  IPAddress myIP = WiFi.softAPIP();  // WiFi.softAPIP()でWiFi起動

  // 各種情報を表示
  Serial.print("SSID: ");
  Serial.println(ssid);
  Serial.print("AP IP address: ");
  Serial.println(myIP);

  // GETリクエストに対するハンドラーを登録
  // rootにアクセスされた時のレスポンス
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(SPIFFS, "/index.html");
  });
  // style.cssにアクセスされた時のレスポンス
  server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(SPIFFS, "/style.css", "text/css");
  });

  // サーバースタート
  server.begin();
  Serial.println("Server start!");
}

void loop() {}

Webページの作成

Webページの保存用フォルダの作成

まずは保存用フォルダを作成します。

PlatformIO

プロジェクトフォルダのルートに「data」フォルダを作成します。

Arduino

.inoと同じフォルダに「data」フォルダを作成します。

Webページの作成

「data」フォルダの中にWebページのデータを保存します。

index.html

<!DOCTYPE html>
<html>
<head>
  <title>ESP32 Web Server</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" href="data:,">
  <link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
  <h1>ESP32 Web Server</h1>
  <p>GPIO state: <strong> %STATE%</strong></p>
  <p><a href="/on"><button class="button">On</button></a></p>
  <p><a href="/off"><button class="button button2">Off</button></a></p>
</body>
</html>

style.css

html {
    font-family: Helvetica;
    display: inline-block;
    margin: 0px auto;
    text-align: center;
  }
  h1{
    color: #0F3376;
    padding: 2vh;
  }
  p{
    font-size: 1.5rem;
  }
  .button {
    display: inline-block;
    background-color: #008CBA;
    border: none;
    border-radius: 4px;
    color: white;
    padding: 16px 40px;
    text-decoration: none;
    font-size: 30px;
    margin: 2px;
    cursor: pointer;
  }
  .button2 {
    background-color: #f44336;

WebページをFlashに書き込む

Arduino

「ツール」メニューから「ESP32 Sketch Data Upload」を実行すると、「data」フォルダに保存されているファイルがFlashに書き込まれます。

PlatformIO

「PROJECT TASK」→「esp32dev」→「Platform」にある「Upload Filesystem Image」を実行することで、「data」フォルダに保存されているファイルがFlashに書き込まれます。

実行

Arduino IDEから「シリアルモニタ」を起動し、ESP32のリセットボタンを押して起動時のログを確認します。
その中からSSIDとIPアドレスが表示されていれば、ESP32がアクセスポイントモードで起動しています。

PCやスマホ等をESP32のアクセスポイントに接続し、設定したIPアドレス(例: 192.168.123.45)にブラウザでアクセスします。
これまでの手順に問題がなければ以下の画面が表示されます。