前回はSPIFFSを使ってHTMLファイルをフラッシュから読み込みました。今回は、Web設計に必要な CSSファイルや画像ファイル、スクリプトファイル等を読み込む機能を追加します。
先ずは CSS ファイルから
この例題スケッチをIDEから読み込んだ時に、server.onNotFound(handleNotFound); という関数が有ったのですが、当時は使わないので削除していました。今回はこれを使います。
server.on()はクリエを元に操作関数と関連付ける関数(例えば、server.on(“/led_on”, handle_led_on);)でした。
server.onNotFound()は、server.on()で定義した以外のクリエを処理する関数を定義する関数です。先ずはスケッチを見て下さい。
#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.onNotFound(handleWebRequests);
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.html", FILE_READ);
while(dataFile.available())
line += (dataFile.readStringUntil('\n') + "\n");
dataFile.close();
return line;
}
void handleWebRequests()
{
String dataType = "text/plain";
String path;
File dataFile;
int flg=0;
path = server.uri();
if(path.endsWith(".css")) { dataType = "text/css"; flg=1; }
delay(5);
if(flg)
{
dataFile = SPIFFS.open(path.c_str(), FILE_READ);
server.streamFile(dataFile, dataType);
dataFile.close();
delay(5);
}
else
{
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i = 0; i < server.args(); i++) {
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(404, "text/plain", message);
}
}
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;
}
- 42行:server.onNotFound(handleWebRequests);
- server.on()で登録したクリエ以外を処理する関数をここで登録
- 処理関数名は、”handleWebRequests”
- 58行:dataFile = SPIFFS.open(“/index_hd.html”, FILE_READ);
- HTMLの固定部を読み込む部分
- 前回からCSS関連を取り除いたので、ファイルネイムを、”/index_hd.txt”から”/index_hd.html”に変更
- 66から99行:void handleWebRequests()
- handleWebRequests()本体。
- 73行:ここでクリエと取得
- 74行:クリエの最後の4文字が、”.css”なら、dataTypeを”text/css”
- 77行:クリエ指定のファイルが”.css”なら下記を実行
- 79,80行:ファイルをオープンしてクライアントに送信
- 84行:クリエ指定のファイルが”.css”で無ければ下記を実行
- 86から97行:本来のHelloスケッチに有った処理そのまま使用
データフォルダーに保存するファイルは、”index_hd.html” と ”led.css”の2つです。先ずは、”index_hd.html”
<!DOCTYPE html>
<html>
<head><meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<link rel='stylesheet' type='text/css' href='/led.css' >
<title>LED Control</title>
</head>
<body>
<h2>Hello ESP32</h2>
<h3>Using SPIFFS</h3>
<h4>Handle CSS</h4>
- 前回から、CSS関係を抜くとこんな感じになります。
- 4行:ここで、CSSファイルとして、”led.css” を指定しています。
- 10行:CSSファイル処理機能を付けたのこの1文を追加しました。
続いて、”led.css”
@charset "UTF-8";
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;
}
- 普通のCSSファイルです。特に説明無し
準備が出来たところで
- 現在のプロダクトフォルダーに、”data”フォルダーを作り、そこに”index_hd.html” と”led.css”を保存
- 先ずはスケッチをコンパイル
- 続いて”index_hd.html” と”led.css”をアップロード
- ”EN”ボタンを押してスケッチを実行
- Webブラウザに、”esp32.local”と入力する。
この画面が出ます

このページのソースコードは、

予定通りです。
その他のファイル
その他のファイルも同様に処理出来ます。今回は、画像ファイルとして、”png”、”gif”、”jpg”の3種類と、java scriptファイルを処理出来る様に変更しています。下記は、”png”とjava scriptファイルを読み込むスケッチの例です
#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.onNotFound(handleWebRequests);
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.html", FILE_READ);
while(dataFile.available())
line += (dataFile.readStringUntil('\n') + "\n");
dataFile.close();
return line;
}
void handleWebRequests()
{
String dataType = "text/plain";
String path;
File dataFile;
int flg=0;
path = server.uri();
if(path.endsWith(".css")) { dataType = "text/css"; flg=1; }
else if(path.endsWith(".js")) { dataType = "application/javascript"; flg=1; }
else if(path.endsWith(".png")) { dataType = "image/png"; flg=1; }
else if(path.endsWith(".gif")) { dataType = "image/gif"; flg=1; }
else if(path.endsWith(".jpg")) { dataType = "image/jpeg"; flg=1; }
delay(5);
if(flg)
{
dataFile = SPIFFS.open(path.c_str(), FILE_READ);
server.streamFile(dataFile, dataType);
dataFile.close();
delay(5);
}
else
{
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i = 0; i < server.args(); i++) {
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(404, "text/plain", message);
}
}
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";
ptr +="<div id='a' title='1'></div>\n";
}
else
{
ptr +="<a class='button button-on' href='/led_on'>ON</a>\n";
ptr +="<div id='a' title='0'></div>\n";
}
ptr +="<script type='text/javascript' src='/test.js'></script>\n";
ptr +="</body>\n";
ptr +="</html>\n";
return ptr;
}
- 75行:ジャバスクリプトファイルの追加
- 76行:png (画像)ファイルの追加
- 78行: gif ファイルの追加
- 78行: jpg ファイルの追加。
- 130行:prt += “<div id=’a’ title=’1′></div>”
- title属性にID を”a”とし、”1”を代入
- 135行:prt += “<div id=’a’ title=’0′></div>”
- title属性にID を”a”とし、”0”を代入
- 137行:ここで外部よりスクリプトファイル、”test.js” を読み込む
”test.js”は、java script ファイルです。
var a = document.getElementById( 'a' ).title;
if(a == '1')
document.write('<img src="/led_on.png" >');
else
document.write('<img src="/led_off.png" >');
- 簡単なスクリプトファイルです。
- ”a”のtitleを読み込んで
- “1”だったら”led_on.png”画像の表示
- それ以外は”led_on.png”画像の表示
“index_hd.html”も書き換えました。
<!DOCTYPE html>
<html>
<head><meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<link rel='stylesheet' type='text/css' href='/led.css' >
<title>LED Control</title>
</head>
<body>
<h2>Hello ESP32</h2>
<h3>Using SPIFFS</h3>
<h4>Handle CSS,JPG,PNG,GIF,JS</h4>
- 最後の行に対応したファイルの拡張子を追加しました。
今回は、画像ファイル、”led_on.png”、”led_on.png”が必要です。これらも”data”フォルダーに予め保存して置きます。
これで準備完了です。コンパイル、DATAのアップロードを行ってから実行して下さい。esp32.localにアクセスすると

この画面が表示されます。ここで、”ON”ボタンを押すと

下の電球がついた状態に変わります。この状態のページのソースは

“png”ファイルはこのコードに有りませんが、これで”CSS”,”JS” ,”PNG”ファイルの処理が行えました。
今回のプロジェクトファアイルを、”ここに” 保存しました。