前回までで、それらしいWebページになったのですが、
- スケッチにHTMLのコード埋め込まれている。HTMLファイルとして扱いたい
- ボタン等のスタイル設定は、CSSファイルを使いたい。
- 画像等のファイルを扱いたい。
ということで、ファイルを扱える様にしたいと思います。
ファイルの扱いはSDかMicroSDカードの様な外部メディアを使うのが一般的と思いますが、ESP32は内部フラッシュを外部メディアの変わりに使う事が出来ます。これをSPIFFS(SPI Flash File System) と言います。”SPI接続された内部フラッシュを使ったファイルシステム”って感じでしょうか。
インストールと使い方の説明は、”ESP32-WROOM-32 SPIFFS アップローダープラグインの使い方”を参照しました。
前回使用したスケッチから、”Webのボタンを押すとファイルからデータを読み込みシリアルモニタにそれを表示する”に変更します。
- 下記のサンプルファイル、”text.txt”をスケッチフォルダの下のdata フォルダに保存
LED Status: "ON"
LED Status: "OFF"
- 修正したスケッチ
#include <WiFi.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#include <SPIFFS.h>
const char* ssid = "XXXXXX";
const char* password = "YYYYYY";
WebServer server(80);
#define LED_pin 2
bool LED_status = LOW;
String index_HD =
"<!DOCTYPE html> <html>\n"
"<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n"
"<title>LED Control</title>\n"
"<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n"
".button {display: block;width: 60px;background-color: #3498db;border: none;color: white;padding: 13px 30px;\n"
"text-decoration: none;font-size: 25px;margin: 0px auto 35px;cursor: pointer;border-radius: 4px;}\n"
".button-on {background-color: #3498db;}\n"
".button-on:active {background-color: #2980b9;}\n"
".button-off {background-color: #34495e;}\n"
".button-off:active {background-color: #2c3e50;}\n"
"</style>\n"
"</head>\n"
"<body>\n"
"<h2>Hello ESP32</h2>\n";
void setup() {
Serial.begin(115200);
pinMode(LED_pin, OUTPUT);
digitalWrite(LED_pin, 0);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("");
// Wait for connection
while (WiFi.status() != WL_CONNECTED){
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (MDNS.begin("esp32")) {
Serial.println("MDNS responder started");
}
server.on("/", handleRoot);
server.on("/led_on", handle_led_on);
server.on("/led_off", handle_led_off);
server.begin();
Serial.println("HTTP server started");
if (!SPIFFS.begin()) {
Serial.println("SPIFFS Mount Failed");
return;
}
}
void loop() {
server.handleClient();
}
void handleRoot() {
LED_status = LOW;
digitalWrite(LED_pin, LOW);
server.send(200, "text/html", SendHTML(LED_status));
}
void handle_led_on() {
LED_status = HIGH;
digitalWrite(LED_pin, HIGH);
server.send(200, "text/html", SendHTML(true));
File dataFile;
dataFile = SPIFFS.open("/test.txt", FILE_READ);
Serial.println(dataFile.readStringUntil('\n'));
dataFile.close();
}
void handle_led_off() {
LED_status = LOW;
digitalWrite(LED_pin, LOW);
server.send(200, "text/html", SendHTML(false));
File dataFile;
dataFile = SPIFFS.open("/test.txt", FILE_READ);
dataFile.readStringUntil('\n');
Serial.println(dataFile.readStringUntil('\n'));
dataFile.close();
}
String SendHTML(uint8_t led_stat){
String ptr;
ptr = index_HD;
if(led_stat)
ptr +="<a class=\"button button-off\" href=\"/led_off\">OFF</a>\n";
else
ptr +="<a class=\"button button-on\" href=\"/led_on\">ON</a>\n";
ptr +="</body>\n";
ptr +="</html>\n";
return ptr;
}
- 4行:#include
- ヘッダーファイルに読み込み
- 62から65行: if (!SPIFFS.begin()) {
- SPIFFSの初期化。エラー処理付き
- 83から87行:
- ここは、ボタンが押されてLEDを点灯させる時に呼び出される関数内
- サンプルファイル、”test.txt”を読み込みモードで開く
- 最初の1行分を読み込み。−> LED Status: “ON”
- それをシリアルモニタに表示してファイルをクローズ。
- 95から100行:
- ボタンが押されてLEDを消灯させる時に呼び出される関数内
- サンプルファイル、”test.txt”を読み込みモードで開く
- 最初の1行分を読み込み捨て。
- 次の1行分を読み込み。 −> LED Status: “OFF”
- それをシリアルモニタに表示してファイルをクローズ。
シリアルモニタを上げて、スケッチを実行して下さい。LEDの動作に合わせてモニタに、LED Status: “ON” または LED Status: “OFF” が表示されます。(”ESP32-WROOM-32 SPIFFS アップローダープラグインの使い方”にもあるのですが、SIPFFSのデータファイルをアップロードする時にはモニターをオフする事を気をつけて下さい)
本題のスケッチ
本題のスケッチを以下の様に書き換えます。
#include <WiFi.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#include <SPIFFS.h>
const char* ssid = "XXXXXX";
const char* password = "YYYYYY";
WebServer server(80);
#define LED_pin 2
bool LED_status = LOW;
void setup() {
Serial.begin(115200);
pinMode(LED_pin, OUTPUT);
digitalWrite(LED_pin, 0);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("");
// Wait for connection
while (WiFi.status() != WL_CONNECTED){
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (MDNS.begin("esp32")) {
Serial.println("MDNS responder started");
}
server.on("/", handleRoot);
server.on("/led_on", handle_led_on);
server.on("/led_off", handle_led_off);
server.begin();
Serial.println("HTTP server started");
SPIFFS.begin();
}
void loop() {
server.handleClient();
}
String load_HD() {
File dataFile;
String line;
dataFile = SPIFFS.open("/index_hd.txt", FILE_READ);
while(dataFile.available())
line += (dataFile.readStringUntil('\n') + "\n");
dataFile.close();
return line;
}
void handleRoot() {
LED_status = LOW;
digitalWrite(LED_pin, LOW);
server.send(200, "text/html", SendHTML(LED_status));
}
void handle_led_on() {
LED_status = HIGH;
digitalWrite(LED_pin, HIGH);
server.send(200, "text/html", SendHTML(true));
}
void handle_led_off() {
LED_status = LOW;
digitalWrite(LED_pin, LOW);
server.send(200, "text/html", SendHTML(false));
}
String SendHTML(uint8_t led_stat){
String ptr;
ptr = load_HD();
if(led_stat)
ptr +="<a class=\"button button-off\" href=\"/led_off\">OFF</a>\n";
else
ptr +="<a class=\"button button-on\" href=\"/led_on\">ON</a>\n";
ptr +="</body>\n";
ptr +="</html>\n";
return ptr;
}
- 4行:#include
- 46行:SPIFFS.begin()
- エラー処理止めました。
- 53から63行:String load_HD() {
- SIPFFSを使ってデータを読み出す関数
- 86行:ptr = load_HD();
- 前回、スケッチ内に埋め込まれていたHTMLをprtに代入していた行
- 今回は、SIPFFSを使って読み込んだデータを代入している。
- それ以降の処理は変更無し。
”index_hd.txt” は以下の通り。
index_hd.txt
<!DOCTYPE html>
<html>
<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">
<title>LED Control</title>
<style>
html {
font-family: Helvetica;
display: inline-block;
margin: 0px auto;
text-align: center;
}
.button {
display: block;
width: 60px;
background-color: #3498db;
border: none;
color: white;
padding: 13px 30px;
text-decoration: none;
font-size: 25px;
margin: 0px auto 35px;
cursor: pointer;
border-radius: 4px;
}
.button-on {
background-color: #3498db;
}
.button-on:active {
background-color: #2980b9;
}
.button-off {
background-color: #34495e;
}
.button-off:active {
background-color: #2c3e50;
}
</style>
</head>
<body>
<h2>Hello ESP32</h2>
<h3>Using SPIFFS</h3>
- 前回スケッチ内で定義していたHTML(下記)の書き換え。
String index_HD =
"<!DOCTYPE html> <html>\n"
"<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n"
"<title>LED Control</title>\n"
"<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n"
".button {display: block;width: 60px;background-color: #3498db;border: none;color: white;padding: 13px 30px;\n"
"text-decoration: none;font-size: 25px;margin: 0px auto 35px;cursor: pointer;border-radius: 4px;}\n"
".button-on {background-color: #3498db;}\n"
".button-on:active {background-color: #2980b9;}\n"
".button-off {background-color: #34495e;}\n"
".button-off:active {background-color: #2c3e50;}\n"
"</style>\n"
"</head>\n"
"<body>\n"
"<h2>Hello ESP32</h2>\n";
- SPIFFSを使っている事を明記する為に、最後に行に、”<h3>Using SPIFFS </h3>”を追加しています。
コンパイル、SPIFFS用データを書き込んだ後実行して下さい。
ちゃんと追加した、”Using SPIFFS”も表示されました。もちろんLEDもボタンの表示も問題無く動作します。ちなみにこの状態でページのソースを表示すると
予想通りの結果です。
現時点では、SPIFFSを使ってファイルを読み込んでいるだけで、CCSファイルや画像ファイル等への対応は出来ていません。次回はそれらへの対応をして行きます。