ESP32 WiFi Server & Web Socket Tutorial
Introduction
This tutorial is designed for anyone that is interested in learning more in using and hosting a WiFi server on the ESP32-S3 devboard and send and communicating realtime using websocket
Learning Objectives
Learn how to create a WiFi Server on ESP32
Learn how to create websocket for immediate signal transfer
Using PlatformIO (instead of Arduino) for faster development
Host a WiFi server (access point) on ESP32
Using Websocket to send realtime command
Background Information
This tutorial is a summary and conclude of our group project of controlling a window cleaning bot through WiFi using phone.
Getting Started
Required Downloads and Installations
VSCode installed
- Including PlatformIO IDE extension
- Link: https://marketplace.visualstudio.com/items?itemName=platformio.platformio-ide
Required Components
Component Name | Quanitity |
---|---|
ESP32-S3 Devboard | 1 |
Required Tools and Equipment
- Laptop/PC
Part 01: Setting Up WiFi Server
Introduction
In this part, you’ll learn how to setup a WiFi server using only the ESP32 Devboard
Objective
- Setup development environment using platformIO
- Setup a WiFi server and display a small webpage on your device
Background Information
Technical skill learn
- How to setup PlatformIO project
- How to setup and run a WiFi server on the ESP32
Components
- ESP32-S3 Devboard
Instructional
- Open Visual Studio Code (without opening any folder)
- Go to PlatformIO tab
- Click on Create New Project
Click on New Project
Enter following information
- Name:
ESP32 Web controller
- Board:
Espressif ESP32-S3-DevKitC-1-N8
- Framework:
Arduino
- Location: Pick your own preferred location
- Name:
Open
platformio.ini
file Type in
[env:esp32-s3-devkitc-1]
platform = espressif32
board = esp32-s3-devkitc-1
framework = arduino
upload_speed = 921600
monitor_speed = 115200
upload_protocol = esptool
lib_deps =
Links2004/WebSockets@^2.3.6
waspinator/AccelStepper@^1.64
bblanchon/ArduinoJson@^7.4.1
build_unflags =
-std=gnu++11
build_flags=
-std=gnu++17
-D ARDUINO_USB_CDC_ON_BOOT=1
-D ARDUINO_USB_MODE=1
-DFORMAT_SPIFFS_IF_FAILED=true
board_build.filesystem = spiffs
extra_scripts = upload_fs.py
- Create a new file
upload_fs.py
This file is use for file uploading
# upload_fs.py
Import("env")
def before_upload_fs(source, target, env):
env.Execute("pio run --target uploadfs")
env.AddPreAction("upload", before_upload_fs)
env.AddPreAction("program", before_upload_fs) # optional: handles manual programming
- Create a
data
directory - Create a file
index.html
in thedata
directory
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>ESP32 Controller</title>
</head>
<body>
<h1>ESP32 Controller</h1>
</body>
</html>
- In
src/main.cpp
, add following code
#include <Arduino.h>
#include <ArduinoJson.h>
#include <string>
#include <SPIFFS.h>
#include <WiFi.h>
inline constexpr const char* WIFI_SSID = "ESP32-Access-Point";
inline constexpr const char* WIFI_PASSWORD = "123456789";
WiFiServer server{80};
void setup() {
Serial.begin(115200);
WiFi.softAP(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Access Point IP: ");
Serial.println(WiFi.softAPIP());
if (!SPIFFS.begin(true)) {
Serial.println("An Error has occurred while mounting SPIFFS");
return;
}
server.begin();
}
void loop() {
WiFiClient client = server.available();
if (client) {
Serial.println("New Client.");
handleClientRequest(client);
client.stop();
Serial.println("Client disconnected.");
}
}
void handleClientRequest(WiFiClient& client) {
String request = client.readStringUntil('\r');
client.read();
if (request.indexOf("GET / ") >= 0) {
File file = SPIFFS.open("/index.html", "r");
if (!file) {
Serial.println("Failed to open /index.html");
client.println("HTTP/1.1 500 Internal Server Error");
client.println("Content-type:text/plain");
client.println("Connection: close");
client.println();
client.println("Failed to load index.html");
return;
}
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println("Connection: close");
client.println();
client.write(file);
while (file.available()) {
client.write(file.read());
}
file.close();
client.println();
}
}
This create a WiFiServer that returns the index.html file whenever user request 192.168.4.1
, which is the default address for esp32 WiFi server.
- Go to PlatformIO extension tab
- Connect ESP32 devboard to your laptop, and change it to boot mode
- Click on
esp32-s3-devkitc-1 > General > Upload and Monitor
- After uploading, go to your phone and look for the WiFi name
ESP32-Access-Point
- Enter the password
123456789
- Open any browser and put in
192.168.4.1
- You will be able to see the webpage
Part 02: Setting Up Web Socket server
Introduction
In this part, you’ll learn how to setup a web socket server using only the ESP32 Devboard
Objective
- Setup a Websocket server and display a small webpage that you can click on button and display it on the serial monitor
Background Information
Technical skill learn
- How to run and communicate through websocket
Components
- ESP32-S3 Devboard
Instructional
- Add following to
src/main.py
#include <WebSocketsServer.h>
WebSocketsServer webSocket{81};
void setup() {
// ...previous code
webSocket.begin();
webSocket.onEvent(onWebSocketEvent);
}
void onWebSocketEvent(uint8_t num, WStype_t type, uint8_t* payload, size_t length) {
if (type == WStype_TEXT) {
String json = (char*)payload;
JsonDocument doc;
deserializeJson(doc, json);
Serial.printf("Recieve Input: %s\n", doc["info"]);
}
}
- Change
data/index.html
to following:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>ESP32 Controller</title>
</head>
<body>
<h1>ESP32 Controller</h1>
<button type="button" onclick="sendButtonPress()" id="info">Hello!</button>
<script>
"use strict";
class WebSocketHandler {
constructor(renderer, statusDisplay, simulator) {
this.socket = null; // Socket for websocket connection
this.reconnectTimeout = null; // Timeout timer
this.reconnectDelay = 2000;
}
connect() {
if (
this.socket &&
(this.socket.readyState === WebSocket.OPEN ||
this.socket.readyState === WebSocket.CONNECTING)
) {
return;
}
this.socket = new WebSocket("ws://" + location.hostname + ":81");
this.socket.onopen = () => {
if (this.reconnectTimeout) {
clearTimeout(this.reconnectTimeout);
this.reconnectDelay = 2000;
this.reconnectTimeout = null;
}
};
this.socket.onclose = this.handleDisconnect.bind(this);
this.socket.onerror = this.handleDisconnect.bind(this);
}
handleDisconnect() {
if (!this.reconnectTimeout) {
this.reconnectTimeout = setTimeout(() => {
this.reconnectTimeout = null;
this.connect();
this.reconnectDelay = Math.min(this.reconnectDelay * 2, 30000); // cap at 30s
}, this.reconnectDelay);
}
}
}
let wsHandler;
function sendButtonPress() {
if (
wsHandler.socket &&
wsHandler.socket.readyState === WebSocket.OPEN
) {
wsHandler.socket.send(JSON.stringify({ info: "Hello!" }));
}
}
window.onload = () => {
wsHandler = new WebSocketHandler();
wsHandler.connect();
window.addEventListener("online", () => {
if (
!wsHandler.socket ||
wsHandler.socket.readyState === WebSocket.CLOSED
) {
wsHandler.connect();
}
});
window.onbeforeunload = () => {
if (
wsHandler.socket &&
wsHandler.socket.readyState === WebSocket.OPEN
) {
wsHandler.socket.close();
}
};
};
</script>
</body>
</html>
- Go to PlatformIO extension tab
- Connect ESP32 devboard to your laptop, and change it to boot mode
- Click on
esp32-s3-devkitc-1 > General > Upload and Monitor
- After uploading, go to your phone and look for the WiFi name
ESP32-Access-Point
- Enter the password
123456789
- Open any browser and put in
192.168.4.1
- You will be able to see the webpage
- After pressing the button, you will be able to see
Recieve Input: Hello!