26 ESP32 web servers
26.1 Introduction
In this tutorial, we will learn how to use the ESP32 as a simple web server.
Instead of sending data over the serial monitor, the ESP32 will create its own Wi-Fi network and host a small web page that you can open from your phone or laptop. This web page can:
- display information (for example, temperature and humidity), and
- receive input (for example, a button click to turn an led on or off).
We will focus on two examples:
- A web server that shows temperature and humidity from the SHT31 sensor.
- A web server that controls the built-in led.
Both examples work without any external Wi-Fi network. The ESP32 itself creates the Wi-Fi network.
26.2 SHT31 on web server
Here is the code for reading temperature and humidity values from the SHT31 sensor and displaying them on a web page.
Download code#include <Arduino.h>
#include <Wire.h>
#include <WiFi.h>
#include <WebServer.h>
#include "Adafruit_SHT31.h"
// ── settings for students to change ───────────────────────────────
// wifi network name created by the esp32 (each student should use a different name)
const char* apSsid = "esp32_sht31_student_1";
// device name shown on the web page
const char* deviceName = "student_1";
// ──────────────────────────────────────────────────────────────────
// sht31 sensor object
Adafruit_SHT31 sht31 = Adafruit_SHT31();
// web server on port 80
WebServer server(80);
// build and send web page
void handleRoot() {
// read temperature and humidity
float temperature = sht31.readTemperature();
float humidity = sht31.readHumidity();
// prepare strings for display
String tempStr = "n/a";
String humStr = "n/a";
if (!isnan(temperature)) {
tempStr = String(temperature, 1); // 1 decimal place
}
if (!isnan(humidity)) {
humStr = String(humidity, 1); // 1 decimal place
}
// simple html page
String page;
page += "<!DOCTYPE html><html><head><meta charset='utf-8'>";
page += "<meta http-equiv='refresh' content='1'>"; // refresh every 1 second
page += "<title>";
page += deviceName;
page += " - SHT31</title>";
page += "<style>";
page += "body{font-family:Arial,Helvetica,sans-serif;max-width:400px;margin:20px auto;}";
page += "</style></head><body>";
page += "<h2>esp32 sensor: ";
page += deviceName;
page += "</h2>";
page += "<p><b>temperature:</b> ";
page += tempStr;
page += " °C</p>";
page += "<p><b>humidity:</b> ";
page += humStr;
page += " %</p>";
page += "<p style='margin-top:20px;font-size:12px;color:#555;'>";
page += "this page refreshes once per second.";
page += "</p>";
page += "</body></html>";
server.send(200, "text/html", page);
}
// handle unknown paths
void handleNotFound() {
server.send(404, "text/plain", "not found");
}
void setup() {
// start serial for debug
Serial.begin(115200);
delay(500);
// start sht31 on i2c address 0x44
if (!sht31.begin(0x44)) {
Serial.println("sht31 not found");
}
// set wifi to access point mode
WiFi.mode(WIFI_AP);
// create open access point (no password)
WiFi.softAP(apSsid);
// print access point info
IPAddress ip = WiFi.softAPIP();
Serial.print("access point ssid: ");
Serial.println(apSsid);
Serial.print("access point ip: ");
Serial.println(ip);
// define http routes
server.on("/", handleRoot);
server.onNotFound(handleNotFound);
// start web server
server.begin();
Serial.println("web server started");
}
void loop() {
// handle incoming http requests
server.handleClient();
}26.3 Toggle LED on web server
Here is the code for toggling the builtin LED from a web page.
Download code#include <Arduino.h>
#include <WiFi.h>
#include <WebServer.h>
// ── settings for students to change ───────────────────────────────
// wifi network name created by the esp32 (each student should use a different name)
const char* apSsid = "esp32_led_student_1";
// ──────────────────────────────────────────────────────────────────
// web server on port 80
WebServer server(80);
// remember led state
bool ledState = false;
// build and send web page
void handleRoot() {
String page;
page += "<!DOCTYPE html><html><head><meta charset='utf-8'>";
page += "<title>esp32 led control</title>";
page += "<style>";
page += "body{font-family:Arial,Helvetica,sans-serif;max-width:400px;margin:20px auto;}";
page += "button{font-size:16px;padding:8px 16px;}";
page += "</style></head><body>";
page += "<h2>esp32 led control</h2>";
page += "<p><b>led state:</b> ";
page += (ledState ? "ON" : "OFF");
page += "</p>";
page += "<form action=\"/toggle\" method=\"GET\">";
page += "<button type=\"submit\">toggle led</button>";
page += "</form>";
page += "</body></html>";
server.send(200, "text/html", page);
}
// toggle led and show main page
void handleToggle() {
ledState = !ledState;
digitalWrite(LED_BUILTIN, ledState ? HIGH : LOW);
handleRoot();
}
// handle unknown paths
void handleNotFound() {
server.send(404, "text/plain", "not found");
}
void setup() {
// start serial for debug
Serial.begin(115200);
delay(500);
// set built-in led pin
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
// set wifi to access point mode
WiFi.mode(WIFI_AP);
// create open access point (no password)
WiFi.softAP(apSsid);
// print access point info
IPAddress ip = WiFi.softAPIP();
Serial.print("access point ssid: ");
Serial.println(apSsid);
Serial.print("access point ip: ");
Serial.println(ip);
// define http routes
server.on("/", handleRoot);
server.on("/toggle", handleToggle);
server.onNotFound(handleNotFound);
// start web server
server.begin();
Serial.println("web server started");
}
void loop() {
// handle incoming http requests
server.handleClient();
}