ESP32 - Webserver met Meerdere Pagina's
In deze tutorial gaan we ontdekken hoe u een ESP32 kunt omzetten in een webserver die meerdere pagina's tegelijk kan afhandelen, zoals index.html, temperature.html, led.html, error_404.html...
Door deze tutorial te volgen, kunt u uw ESP32 omtoveren tot een webserver met interessante mogelijkheden:
Meerdere webpagina's zijn tegelijkertijd actief.
De HTML-inhoud (inclusief HTML, CSS en Javascript) voor elke pagina wordt apart bewaard in een eigen bestand binnen de Arduino IDE.
De HTML-inhoud kan dynamisch worden bijgewerkt met realtime waarden van sensoren, waardoor de webpagina's dynamisch en responsief zijn.
De webserver maakt het mogelijk om iets aan te sturen dat via de ESP32 verbonden is, via het web.
De webserver handelt HTTP-foutcodes af, zoals de 404 Not Found.
Het klinkt misschien ingewikkeld, maar maak u geen zorgen! Deze tutorial geeft stap-voor-stap uitleg en de code is ontworpen om ook voor beginners makkelijk te begrijpen zodat u eenvoudig uw eigen ESP32-webserver kunt maken.
Of u kunt de volgende kits kopen:
Openbaarmaking: Sommige van de links in deze sectie zijn Amazon-affiliate links. We kunnen een commissie ontvangen voor aankopen die via deze links worden gedaan, zonder extra kosten voor u. We waarderen uw steun.
Bent u nog niet bekend met ESP32 en webservers (waaronder pinout, werking en programmeren), dan kunt u hierover leren via de volgende tutorials:
Hieronder vindt u de volledige ESP32-code die een webserver met meerdere pagina's aanmaakt. Om het eenvoudig te houden is de HTML-inhoud voor elke pagina erg simpel en direct in de ESP32-code verwerkt. In een volgend deel zullen we leren hoe de HTML-inhoud per pagina apart kan worden opgeslagen in verschillende bestanden, zodat de code overzichtelijker en beter beheersbaar wordt.
#include <DIYables_ESP32_WebServer.h>
#define LED_PIN 18
int LED_state = LOW;
float getTemperature() {
float temp_x100 = random(0, 10000);
return temp_x100 / 100;
}
const char WIFI_SSID[] = "YOUR_WIFI_SSID";
const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD";
DIYables_ESP32_WebServer server;
void handleHome(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) {
Serial.println("Web Server: home page");
server.sendResponse(client, "This is the ESP32 home page");
}
void handleTemperature(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) {
Serial.println("Web Server: temperature page");
float temperature = getTemperature();
String reponse = "Temperature: " + String(temperature);
server.sendResponse(client, reponse.c_str());
}
void handleLed(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) {
Serial.println("Web Server: LED page");
String state = "";
for (int i = 0; i < params.count; i++) {
if (String(params.params[i].key) == "state") {
state = params.params[i].value;
if (state == "on") {
LED_state = HIGH;
} else if (state == "off") {
LED_state = LOW;
}
digitalWrite(LED_PIN, LED_state);
Serial.print(" => turning LED to ");
Serial.print(state);
Serial.println();
break;
}
}
String reponse = "LED state: " + String(LED_state);
server.sendResponse(client, reponse.c_str());
}
void handleNotFound(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) {
String response = "<!DOCTYPE html><html><head><meta charset=\"UTF-8\"><title>404 Not Found</title></head><body>";
response += "<h1>404 - Page Not Found</h1>";
response += "<p>Sorry, we couldn't find that page!</p>";
response += "<a href=\"/\">Return to Home</a></body></html>";
server.sendResponse(client, response.c_str());
}
void setup() {
Serial.begin(9600);
delay(1000);
pinMode(LED_PIN, OUTPUT);
Serial.println("ESP32 Web Server");
server.addRoute("/", handleHome);
server.addRoute("/temperature.html", handleTemperature);
server.addRoute("/led.html", handleLed);
server.setNotFoundHandler(handleNotFound);
server.begin(WIFI_SSID, WIFI_PASSWORD);
}
void loop() {
server.handleClient();
}
Maak de bekabeling volgens bovenstaande afbeelding.
Verbind de ESP32-board via een micro USB-kabel met uw PC.
Open Arduino IDE op uw PC.
Selecteer het juiste ESP32-board (bijvoorbeeld ESP32 Dev Module) en de juiste COM-poort.
Open de Library Manager door op het Library Manager-icoon in de linkernavigatiebalk van Arduino IDE te klikken.
Zoek op “DIYables ESP32 WebServer” en vind de Web Server bibliotheek gemaakt door DIYables.
Klik op de Installeren-knop om de Web Server bibliotheek te installeren.
Kopieer bovenstaande code en open deze met Arduino IDE.
Pas in de code de WiFi-informatie (SSID en wachtwoord) aan naar die van uzelf.
Klik op de Upload-knop in Arduino IDE om de code naar de ESP32 te uploaden.
Open de Seriële Monitor.
Bekijk de resultaten in de Seriële Monitor.
Connecting to WiFi...
Connected to WiFi
ESP32 Web Server's IP address: 192.168.0.2
ESP32 Web server started
U ziet een IP-adres verschijnen in de Seriële Monitor, bijvoorbeeld: 192.168.0.2
Typ onderstaande adressen één voor één in de adresbalk van een webbrowser op uw smartphone of PC.
192.168.0.2
192.168.0.2/index.html
192.168.0.2/led.html
192.168.0.2/led.html?state=on
192.168.0.2/led.html?state=off
192.168.0.2/temperature.html
192.168.0.2/blabla.html
Let op dat u het IP-adres 192.168.0.2 vervangt door het IP-adres dat in uw Seriële Monitor verschijnt.
U ziet de volgende pagina's: startpagina, led-pagina, temperatuurpagina en een Niet Gevonden-pagina.
U kunt ook het output in de Seriële Monitor volgen.
Connecting to WiFi...
Connected to WiFi
ESP32 Web Server's IP address: 192.168.0.2
ESP32 Web server started
Web Server: home page
Web Server: LED page
Web Server: LED page => turning LED to on
Web Server: LED page => turning LED to off
Web Server: temperature page
Web Server: Not Found
De bovenstaande code heeft voor elke pagina een heel eenvoudige HTML-inhoud. Maar als u een uitgebreide interface wilt maken met veel HTML, dan wordt de code groot en onoverzichtelijk. Om het eenvoudiger te maken, gaan we leren hoe we de HTML kunnen scheiden van de ESP32-code. Hierdoor kunt u de HTML in aparte bestanden bewaren, wat beter te beheren is en prettiger werkt.
#include <DIYables_ESP32_WebServer.h>
#include "index.h"
#include "temperature.h"
#include "led.h"
#include "error_404.h"
#define LED_PIN 18
int LED_state = LOW;
float getTemperature() {
float temp_x100 = random(0, 10000);
return temp_x100 / 100;
}
const char WIFI_SSID[] = "YOUR_WIFI_SSID";
const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD";
DIYables_ESP32_WebServer server;
void handleHome(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) {
Serial.println("Web Server: home page");
server.sendResponse(client, HTML_CONTENT_HOME);
}
void handleTemperature(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) {
Serial.println("Web Server: temperature page");
float temperature = getTemperature();
String html = HTML_CONTENT_TEMPERATURE;
html.replace("%TEMPERATURE_VALUE%", String(temperature));
server.sendResponse(client, html.c_str());
}
void handleLed(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) {
Serial.println("Web Server: LED page");
String state = "";
for (int i = 0; i < params.count; i++) {
if (String(params.params[i].key) == "state") {
state = params.params[i].value;
if (state == "on") {
LED_state = HIGH;
} else if (state == "off") {
LED_state = LOW;
}
digitalWrite(LED_PIN, LED_state);
Serial.print(" => turning LED to ");
Serial.print(state);
Serial.println();
break;
}
}
String html = HTML_CONTENT_LED;
html.replace("%LED_STATE%", LED_state ? "ON" : "OFF");
server.sendResponse(client, html.c_str());
}
void handleNotFound(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) {
Serial.println("Web Server: Not Found");
server.sendResponse(client, HTML_CONTENT_404);
}
void setup() {
Serial.begin(9600);
delay(1000);
pinMode(LED_PIN, OUTPUT);
Serial.println("ESP32 Web Server");
server.addRoute("/", handleHome);
server.addRoute("/temperature.html", handleTemperature);
server.addRoute("/led.html", handleLed);
server.setNotFoundHandler(handleNotFound);
server.begin(WIFI_SSID, WIFI_PASSWORD);
}
void loop() {
server.handleClient();
}
Pas de WiFi-informatie (SSID en wachtwoord) in de code aan naar die van u.
Maak het index.h bestand aan in Arduino IDE door:
const char *HTML_CONTENT_HOME = R"=====(
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="data:,">
<title>Home Page</title>
</head>
<body>
<h1>Welcome to the Home Page</h1>
<ul>
<li><a href="/led.html">LED Page</a></li>
<li><a href="/temperature.html">Temperature Page</a></li>
</ul>
</body>
</html>
)=====";
const char *HTML_CONTENT_LED = R"=====(
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="data:,">
<title>LED Page</title>
</head>
<body>
<h1>LED Page</h1>
<p>LED State: <span style="color: red;">%LED_STATE%</span></p>
<a href='/led.html?state=on'>Turn ON</a>
<br><br>
<a href='/led.html?state=off'>Turn OFF</a>
</body>
</html>
)=====";
const char *HTML_CONTENT_TEMPERATURE = R"=====(
<!DOCTYPE html>
<html>
<head>
<title>ESP32 - Web Temperature</title>
<meta name="viewport" content="width=device-width, initial-scale=0.7, maximum-scale=0.7">
<meta charset="utf-8">
<link rel="icon" href="https://diyables.io/images/page/diyables.svg">
<style>
body { font-family: "Georgia"; text-align: center; font-size: width/2pt;}
h1 { font-weight: bold; font-size: width/2pt;}
h2 { font-weight: bold; font-size: width/2pt;}
button { font-weight: bold; font-size: width/2pt;}
</style>
<script>
var cvs_width = 200, cvs_height = 450;
function init() {
var canvas = document.getElementById("cvs");
canvas.width = cvs_width;
canvas.height = cvs_height + 50;
var ctx = canvas.getContext("2d");
ctx.translate(cvs_width/2, cvs_height - 80);
update_view(%TEMPERATURE_VALUE%);
}
function update_view(temp) {
var canvas = document.getElementById("cvs");
var ctx = canvas.getContext("2d");
var radius = 70;
var offset = 5;
var width = 45;
var height = 330;
ctx.clearRect(-cvs_width/2, -350, cvs_width, cvs_height);
ctx.strokeStyle="blue";
ctx.fillStyle="blue";
var x = -width/2;
ctx.lineWidth=2;
for (var i = 0; i <= 100; i+=5) {
var y = -(height - radius)*i/100 - radius - 5;
ctx.beginPath();
ctx.lineTo(x, y);
ctx.lineTo(x - 20, y);
ctx.stroke();
}
ctx.lineWidth=5;
for (var i = 0; i <= 100; i+=20) {
var y = -(height - radius)*i/100 - radius - 5;
ctx.beginPath();
ctx.lineTo(x, y);
ctx.lineTo(x - 25, y);
ctx.stroke();
ctx.font="20px Georgia";
ctx.textBaseline="middle";
ctx.textAlign="right";
ctx.fillText(i.toString(), x - 35, y);
}
ctx.lineWidth=16;
ctx.beginPath();
ctx.arc(0, 0, radius, 0, 2 * Math.PI);
ctx.stroke();
ctx.beginPath();
ctx.rect(-width/2, -height, width, height);
ctx.stroke();
ctx.beginPath();
ctx.arc(0, -height, width/2, 0, 2 * Math.PI);
ctx.stroke();
ctx.fillStyle="#e6e6ff";
ctx.beginPath();
ctx.arc(0, 0, radius, 0, 2 * Math.PI);
ctx.fill();
ctx.beginPath();
ctx.rect(-width/2, -height, width, height);
ctx.fill();
ctx.beginPath();
ctx.arc(0, -height, width/2, 0, 2 * Math.PI);
ctx.fill();
ctx.fillStyle="#ff1a1a";
ctx.beginPath();
ctx.arc(0, 0, radius - offset, 0, 2 * Math.PI);
ctx.fill();
temp = Math.round(temp * 100) / 100;
var y = (height - radius)*temp/100.0 + radius + 5;
ctx.beginPath();
ctx.rect(-width/2 + offset, -y, width - 2*offset, y);
ctx.fill();
ctx.fillStyle="red";
ctx.font="bold 34px Georgia";
ctx.textBaseline="middle";
ctx.textAlign="center";
ctx.fillText(temp.toString() + "°C", 0, 100);
}
window.onload = init;
</script>
</head>
<body>
<h1>ESP32 - Web Temperature</h1>
<canvas id="cvs"></canvas>
</body>
</html>
)=====";
const char *HTML_CONTENT_404 = R"=====(
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="data:,">
<title>404 - Page Not Found</title>
<style>
h1 {color: #ff4040;}
</style>
</head>
<body>
<h1>404</h1>
<p>Oops! The page you are looking for could not be found on Esp32 Web Server.</p>
<p>Please check the URL or go back to the <a href="/">homepage</a>.</p>
<p>Or check <a href="https://esp32io.com/tutorials/esp32-web-server-multiple-pages"> Esp32 Web Server</a> tutorial.</p>
</body>
</html>
)=====";
Klik op de Upload-knop in Arduino IDE om de code te uploaden naar de ESP32.
Bezoek de webpagina's van de ESP32 via uw webbrowser één voor één zoals eerder. U ziet alle webpagina's zoals hieronder afgebeeld: