This tutorial shows how to build an ESP32 web server that displays a web page with multiple sliders. The sliders control the duty cycle of different PWM channels to control the brightness of multiple LEDs. Instead of LEDs, you can use this project to control DC motors or other actuators that require a PWM signal. The communication between the clients and the ESP32 is done using WebSocket protocol. Additionally, whenever there’s a change, all clients update their slider values simultaneously.
You can also modify the code presented in this tutorial to add sliders to your projects to set threshold values or any other values you need to use in your code.
For this project, the ESP32 board will be programmed using the Arduino core. You can either use the Arduino IDE, VS Code with PlatformIO, or any other suitable IDE.
To better understand how this project works, we recommend taking a look at the following tutorials:
- ESP32 PWM with Arduino IDE (Analog Output)
- ESP32 WebSocket Server: Control Outputs (Arduino IDE)
- ESP32 Web Server with Slider: Control LED Brightness (PWM)*
* This project shows how to build a web server with one slider, but it uses HTTP requests—in this tutorial, we’ll use WebSocket protocol.
We have a similar tutorial for the ESP8266 NodeMCU board:
Project Overview
The following image shows the web page we’ll build for this project:
- The web page contains three cards;
- Each card has a paragraph to display the card title (Fader 1, Fader 2, Fader 3);
- There’s a range slider in each card that you can move to set the brightness of the corresponding LED;
- In each card, another paragraph displays the current LED brightness (in percentage);
- When you set a new position for the slider, it updates all clients (if you have multiple web browser tabs opened (or multiple devices), they update almost simultaneously whenever there’s a change).
How it Works?
- The ESP hosts a web server that displays a web page with three sliders;
- When you set a new position for a slider, the client sends the slider number and slider value to the server via WebSocket protocol. For example, if you set slider number 3 to position number 40, it would send this message 3s40 to the server.
- The server (ESP) receives the slider number and corresponding value and adjusts the PWM duty cycle accordingly. Additionally, it also notifies all the other clients with the new current slider values—this allows us to have all clients updated almost instantaneously.
- The ESP32 outputs the PWM signal with the corresponding duty cycle to control the LED brightness. A duty cycle of 0% means the LED is completely off, a duty cycle of 50% means the LED is half lit, and a duty cycle of 100% means the LED is lit;
- Whenever you open a new web browser window (this is when a new client connects), it will send a message to the ESP32 (also through WebSocket protocol) with the message getValues. When the ESP32 gets this message, it sends the current slider values. This way, whenever you open a new tab, it always shows the current and updated values.
Prerequisites
Before proceeding with this tutorial, make sure you check all the following prerequisites.
1) Parts Required
To follow this project you need:
- ESP32 Board – read ESP32 Development Boards Review and Comparison
- 3x LEDs
- 3x 220Ohm resistors
- Breadboard
- Jumper wires
You don’t need three LEDs to test this project, you can simply see the results in the Serial Monitor or use other actuators that required a PWM signal to operate.
You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!
2) Arduino IDE and ESP32 Boards Add-on
We’ll program the ESP32 using Arduino IDE. So, you must have the ESP32 add-on installed. Follow the next tutorial if you haven’t already:
If you want to use VS Code with the PlatformIO extension, follow the next tutorial instead to learn how to program the ESP32:
3) Filesystem Uploader Plugin
To upload the HTML, CSS, and JavaScript files needed to build this project to the ESP32 flash memory (LittleFS), we’ll use a plugin for Arduino IDE: LittleFS Filesystem uploader. Follow the next tutorial to install the filesystem uploader plugin if you haven’t already:
If you’re using VS Code with the PlatformIO extension, read the following tutorial to learn how to upload files to the filesystem:
4) Libraries
To build this project, you need to install the following libraries:
- Arduino_JSON library by Arduino version 0.1.0 (Arduino Library Manager)
- ESPAsyncWebServer (.zip folder);
- AsyncTCP (.zip folder).
You can install the first library using the Arduino Library Manager. Go to Sketch > Include Library > Manage Libraries and search for the library name.
The ESPAsyncWebServer and AsynTCP libraries aren’t available to install through the Arduino Library Manager, so you need to copy the library files to the Arduino Installation Libraries folder. Alternatively, in your Arduino IDE, you can go to Sketch> Include Library > Add .zip Library and select the libraries you’ve just downloaded.
Installing Libraries (VS Code + PlatformIO)
If you’re programming the ESP32 using PlatformIO, you should add the following lines to the platformio.ini file to include the libraries and set the default filesystem to LittleFS (also change the Serial Monitor speed to 115200):
monitor_speed = 115200
lib_deps = ESP Async WebServer
arduino-libraries/Arduino_JSON @ 0.1.0
board_build.filesystem = littlefs
Schematic Diagram
Wire three LEDs to the ESP32. We’re using GPIOs 12, 13, and 14. You can use any other suitable GPIOs.
Recommended reading: ESP32 Pinout Reference: Which GPIO pins should you use?
Organizing Your Files
To keep the project organized and make it easier to understand, we’ll create four files to build the web server:
- Arduino sketch that handles the web server;
- index.html: to define the content of the web page;
- sytle.css: to style the web page;
- script.js: to program the behavior of the web page—handle what happens when you move the slider, send, receive and interpret the messages received via WebSocket protocol.
You should save the HTML, CSS, and JavaScript files inside a folder called data inside the Arduino sketch folder, as shown in the previous diagram. We’ll upload these files to the ESP32 filesystem (LittleFS).
You can download all project files:
HTML File
Copy the following to the index.html file.
<!-- Complete project details: https://randomnerdtutorials.com/esp32-web-server-websocket-sliders/ -->
<!DOCTYPE html>
<html>
<head>
<title>ESP IOT DASHBOARD</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/png" href="favicon.png">
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div class="topnav">
<h1>Multiple Sliders</h1>
</div>
<div class="content">
<div class="card-grid">
<div class="card">
<p class="card-title">Fader 1</p>
<p class="switch">
<input type="range" onchange="updateSliderPWM(this)" id="slider1" min="0" max="100" step="1" value ="0" class="slider">
</p>
<p class="state">Brightness: <span id="sliderValue1"></span> %</p>
</div>
<div class="card">
<p class="card-title"> Fader 2</p>
<p class="switch">
<input type="range" onchange="updateSliderPWM(this)" id="slider2" min="0" max="100" step="1" value ="0" class="slider">
</p>
<p class="state">Brightness: <span id="sliderValue2"></span> %</p>
</div>
<div class="card">
<p class="card-title"> Fader 3</p>
<p class="switch">
<input type="range" onchange="updateSliderPWM(this)" id="slider3" min="0" max="100" step="1" value ="0" class="slider">
</p>
<p class="state">Brightness: <span id="sliderValue3"></span> %</p>
</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
Let’s take a quick look at the most relevant parts of the HTML file.
Creating a Slider
The following tags create the card for the first slider (Fader 1).
<div class="card">
<p class="card-title">Fader 1</p>
<p class="switch">
<input type="range" onchange="updateSliderPWM(this)" id="slider1" min="0" max="100" step="1" value ="0" class="slider">
</p>
<p class="state">Brightness: <span id="sliderValue1"></span> %</p>
</div>
The first paragraph displays a title for the card (Fader 1). You can change the text to whatever you want.
<p class="card-title">Fader 1</p>
To create a slider in HTML you use the <input> tag. The <input> tag specifies a field where the user can enter data.
There are a wide variety of input types. To define a slider, use the type attribute with the range value. In a slider, you also need to define the minimum and the maximum range using the min and max attributes (in this case, 0 and 100, respectively).
You also need to define other attributes like:
- the step attribute specifies the interval between valid numbers. In our case, we set it to 1;
- the class to style the slider (class=”slider”);
- the id so that we can manipulate the slider value using JavaScript (id=”slider1″);
- the onchange attribute to call a function (updateSliderPWM(this)) when you set a new position for the slider. This function (defined in the JavaScript file) sends the current slider value via the WebSocket protocol to the client. The this keyword refers to the HTML slider element.
The slider is inside a paragraph with the switch class name. So, here are the tags that actually create the slider.
<p class="switch">
<input type="range" onchange="updateSliderPWM(this)" id="slider1" min="0" max="100" step="1" value ="0" class="slider">
</p>
Finally, there’s a paragraph with a <span> tag, so that we can insert the current slider value in that paragraph by referring to its id (id=”sliderValue1″).
<p class="state">Brightness: <span id="sliderValue1"></span> %</p>
Creating More Sliders
To create more sliders, you need to copy all the HTML tags that create the complete card. First, however, you need to consider that you need a unique id for each slider and slider value. In our case, we have three sliders with the following ids: slider1, slider2, slider3, and three placeholders for the slider value with the following ids: sliderValue1, sliderValue2, sliderValue3.
For example, here’s the card for slider number 2.
<div class="card">
<p class="card-title"> Fader 2</p>
<p class="switch">
<input type="range" onchange="updateSliderPWM(this)" id="slider2" min="0" max="100" step="1" value ="0" class="slider">
</p>
<p class="state">Brightness: <span id="sliderValue2"></span> %</p>
</div>
CSS File
Copy the following to the style.css file.
/* Complete project details: https://randomnerdtutorials.com/esp32-web-server-websocket-sliders/ */
html {
font-family: Arial, Helvetica, sans-serif;
display: inline-block;
text-align: center;
}
h1 {
font-size: 1.8rem;
color: white;
}
p {
font-size: 1.4rem;
}
.topnav {
overflow: hidden;
background-color: #0A1128;
}
body {
margin: 0;
}
.content {
padding: 30px;
}
.card-grid {
max-width: 700px;
margin: 0 auto;
display: grid;
grid-gap: 2rem;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
.card {
background-color: white;
box-shadow: 2px 2px 12px 1px rgba(140,140,140,.5);
}
.card-title {
font-size: 1.2rem;
font-weight: bold;
color: #034078
}
.state {
font-size: 1.2rem;
color:#1282A2;
}
.slider {
-webkit-appearance: none;
margin: 0 auto;
width: 100%;
height: 15px;
border-radius: 10px;
background: #FFD65C;
outline: none;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 30px;
height: 30px;
border-radius: 50%;
background: #034078;
cursor: pointer;
}
.slider::-moz-range-thumb {
width: 30px;
height: 30px;
border-radius: 50% ;
background: #034078;
cursor: pointer;
}
.switch {
padding-left: 5%;
padding-right: 5%;
}
Let’s take a quick look at the relevant parts of the CSS file that style the slider. In this example, we need to use the vendor prefixes for the appearance attribute.
.slider {
-webkit-appearance: none;
margin: 0 auto;
width: 100%;
height: 15px;
border-radius: 10px;
background: #FFD65C;
outline: none;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 30px;
height: 30px;
border-radius: 50%;
background: #034078;
cursor: pointer;
}
.slider::-moz-range-thumb {
width: 30px;
height: 30px;
border-radius: 50% ;
background: #034078;
cursor: pointer;
}
.switch {
padding-left: 5%;
padding-right: 5%;
}
Vendor Prefixes
Vendor prefixes allow a browser to support new CSS features before they become fully supported. The most commonly used browsers use the following prefixes:
- -webkit- Chrome, Safari, newer versions of Opera, almost all iOS browsers,
- -moz- Firefox,
- -o- Old versions of Opera,
- -ms- Microsoft Edge and Internet Explorer.
Vendor prefixes are temporary. Once the properties are fully supported by the browser you use, you don’t need them. You can use the following reference to check if the property you’re using needs prefixes: shouldiprefix.com
Let’s take a look at the .slider selector (styles the slider itself):
.slider {
-webkit-appearance: none;
margin: 0 auto;
width: 100%;
height: 15px;
border-radius: 10px;
background: #FFD65C;outline: none;
}
Setting -webkit-appearance to none overrides the default CSS styles applied to the slider in Google Chrome, Safari, and Android browsers.
-webkit-appearance: none;
Setting the margin to 0 auto aligns the slider inside its parent container.
margin: 0 auto;
The width of the slider is set to 100% and the height to 15px. The border-radius is set to 10px.
margin: 0 auto;
width: 100%;
height: 15px;
border-radius: 10px;
Set the background color for the slider and set the outline to none.
background: #FFD65C;
outline: none;
Then, format the slider handle. Use -webkit- for Chrome, Opera, Safari and Edge web browsers and -moz- for Firefox.
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 30px;
height: 30px;
border-radius: 50%;
background: #034078;
cursor: pointer;
}
.slider::-moz-range-thumb {
width: 30px;
height: 30px;
border-radius: 50% ;
background: #034078;
cursor: pointer;
}
Set the -webkit-appearance and appearance properties to none to override default properties.
-webkit-appearance: none;
appearance: none;
Set a specific width, height and border-radius for the handler. Setting the same width and height with a border-radius of 50% creates a circle.
width: 30px;
height: 30px;
border-radius: 50%;
Then, set a color for the background and set the cursor to a pointer.
background: #034078;
cursor: pointer;
Feel free to play with the slider properties to give it a different look.
JavaScript File
Copy the following to the script.js file.
// Complete project details: https://randomnerdtutorials.com/esp32-web-server-websocket-sliders/
var gateway = `ws://${window.location.hostname}/ws`;
var websocket;
window.addEventListener('load', onload);
function onload(event) {
initWebSocket();
}
function getValues(){
websocket.send("getValues");
}
function initWebSocket() {
console.log('Trying to open a WebSocket connection…');
websocket = new WebSocket(gateway);
websocket.onopen = onOpen;
websocket.onclose = onClose;
websocket.onmessage = onMessage;
}
function onOpen(event) {
console.log('Connection opened');
getValues();
}
function onClose(event) {
console.log('Connection closed');
setTimeout(initWebSocket, 2000);
}
function updateSliderPWM(element) {
var sliderNumber = element.id.charAt(element.id.length-1);
var sliderValue = document.getElementById(element.id).value;
document.getElementById("sliderValue"+sliderNumber).innerHTML = sliderValue;
console.log(sliderValue);
websocket.send(sliderNumber+"s"+sliderValue.toString());
}
function onMessage(event) {
console.log(event.data);
var myObj = JSON.parse(event.data);
var keys = Object.keys(myObj);
for (var i = 0; i < keys.length; i++){
var key = keys[i];
document.getElementById(key).innerHTML = myObj[key];
document.getElementById("slider"+ (i+1).toString()).value = myObj[key];
}
}
Here’s a list of what this code does:
- initializes a WebSocket connection with the server;
- sends a message to the server to get the current slider values;
- uses the response to update the slider values on the web page;
- handles data exchange through the WebSocket protocol.
Let’s take a look at this JavaScript code to see how it works.
The gateway is the entry point to the WebSocket interface. window.location.hostname gets the current page address (the web server IP address).
var gateway = ws://${window.location.hostname}/ws;
Create a new global variable called websocket.
var websocket;
Add an event listener that will call the onload function when the web page loads.
window.addEventListener('load', onload);
The onload() function calls the initWebSocket() function to initialize a WebSocket connection with the server.
function onload(event) {
initWebSocket();
}
The initWebSocket() function initializes a WebSocket connection on the gateway defined earlier. We also assign several callback functions for when the WebSocket connection is opened, closed, or when a message is received.
function initWebSocket() {
console.log('Trying to open a WebSocket connection…');
websocket = new WebSocket(gateway);
websocket.onopen = onOpen;
websocket.onclose = onClose;
websocket.onmessage = onMessage;
}
Note that when the websocket connection in open, we’ll call the getValues function.
function onOpen(event) {
console.log('Connection opened');
getValues();
}
The getValues() function sends a message to the server getValues to get the current value of all sliders. Then, we must handle what happens when we receive that message on the server side (ESP32).
function getStates(){
websocket.send("getValues");
}
We handle the messages received via websocket protocol on the onMessage() function.
function onMessage(event) {
console.log(event.data);
var myObj = JSON.parse(event.data);
var keys = Object.keys(myObj);
for (var i = 0; i < keys.length; i++){
var key = keys[i];
document.getElementById(key).innerHTML = myObj[key];
document.getElementById("slider"+ (i+1).toString()).value = myObj[key];
}
}
The server sends the states in JSON format, for example:
{
sliderValue1 : 20;
sliderValue2: 50;
sliderValue3: 0;
}
The onMessage() function simply goes through all the values and places them on the corresponding places on the HTML page.
The updateSliderPWM() function runs when you move the sliders.
function updateSliderPWM(element) {
var sliderNumber = element.id.charAt(element.id.length-1);
var sliderValue = document.getElementById(element.id).value;
document.getElementById("sliderValue"+sliderNumber).innerHTML = sliderValue;
console.log(sliderValue);
websocket.send(sliderNumber+"s"+sliderValue.toString());
}
This function gets the value from the slider and updates the corresponding paragraph with the right value. This function also sends a message to the server so that the ESP32 updates the LED brightness.
websocket.send(sliderNumber+"s"+sliderValue.toString());
The message is sent in the following format:
- slidernumbersslidervalue
For example, if you move slider number 3 to position 40, it will send the following message:
3s40
Arduino Sketch
Copy the following code to your Arduino IDE or to the main.cpp file if you’re using PlatformIO.
/*
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at https://RandomNerdTutorials.com/esp32-web-server-websocket-sliders/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
#include <Arduino.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include "LittleFS.h"
#include <Arduino_JSON.h>
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_SSID";
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
// Create a WebSocket object
AsyncWebSocket ws("/ws");
// Set LED GPIO
const int ledPin1 = 12;
const int ledPin2 = 13;
const int ledPin3 = 14;
String message = "";
String sliderValue1 = "0";
String sliderValue2 = "0";
String sliderValue3 = "0";
int dutyCycle1;
int dutyCycle2;
int dutyCycle3;
// setting PWM properties
const int freq = 5000;
const int ledChannel1 = 0;
const int ledChannel2 = 1;
const int ledChannel3 = 2;
const int resolution = 8;
//Json Variable to Hold Slider Values
JSONVar sliderValues;
//Get Slider Values
String getSliderValues(){
sliderValues["sliderValue1"] = String(sliderValue1);
sliderValues["sliderValue2"] = String(sliderValue2);
sliderValues["sliderValue3"] = String(sliderValue3);
String jsonString = JSON.stringify(sliderValues);
return jsonString;
}
// Initialize LittleFS
void initFS() {
if (!LittleFS.begin()) {
Serial.println("An error has occurred while mounting LittleFS");
}
else{
Serial.println("LittleFS mounted successfully");
}
}
// Initialize WiFi
void initWiFi() {
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi ..");
while (WiFi.status() != WL_CONNECTED) {
Serial.print('.');
delay(1000);
}
Serial.println(WiFi.localIP());
}
void notifyClients(String sliderValues) {
ws.textAll(sliderValues);
}
void handleWebSocketMessage(void *arg, uint8_t *data, size_t len) {
AwsFrameInfo *info = (AwsFrameInfo*)arg;
if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT) {
data[len] = 0;
message = (char*)data;
if (message.indexOf("1s") >= 0) {
sliderValue1 = message.substring(2);
dutyCycle1 = map(sliderValue1.toInt(), 0, 100, 0, 255);
Serial.println(dutyCycle1);
Serial.print(getSliderValues());
notifyClients(getSliderValues());
}
if (message.indexOf("2s") >= 0) {
sliderValue2 = message.substring(2);
dutyCycle2 = map(sliderValue2.toInt(), 0, 100, 0, 255);
Serial.println(dutyCycle2);
Serial.print(getSliderValues());
notifyClients(getSliderValues());
}
if (message.indexOf("3s") >= 0) {
sliderValue3 = message.substring(2);
dutyCycle3 = map(sliderValue3.toInt(), 0, 100, 0, 255);
Serial.println(dutyCycle3);
Serial.print(getSliderValues());
notifyClients(getSliderValues());
}
if (strcmp((char*)data, "getValues") == 0) {
notifyClients(getSliderValues());
}
}
}
void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) {
switch (type) {
case WS_EVT_CONNECT:
Serial.printf("WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str());
break;
case WS_EVT_DISCONNECT:
Serial.printf("WebSocket client #%u disconnected\n", client->id());
break;
case WS_EVT_DATA:
handleWebSocketMessage(arg, data, len);
break;
case WS_EVT_PONG:
case WS_EVT_ERROR:
break;
}
}
void initWebSocket() {
ws.onEvent(onEvent);
server.addHandler(&ws);
}
void setup() {
Serial.begin(115200);
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
initFS();
initWiFi();
// Set up LEDC pins
ledcAttachChannel(ledPin1, freq, resolution, ledChannel1);
ledcAttachChannel(ledPin2, freq, resolution, ledChannel2);
ledcAttachChannel(ledPin3, freq, resolution, ledChannel3);
initWebSocket();
// Web Server Root URL
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(LittleFS, "/index.html", "text/html");
});
server.serveStatic("/", LittleFS, "/");
// Start server
server.begin();
}
void loop() {
ledcWrite(ledPin1, dutyCycle1);
ledcWrite(ledPin2, dutyCycle2);
ledcWrite(ledPin3, dutyCycle3);
ws.cleanupClients();
}
How the Code Works
Let’s take a quick look at the relevant parts for this project. To better understand how the code works, we recommend following this tutorial about WebSocket protocol with the ESP32 and this tutorial about PWM with the ESP32.
Insert your network credentials in the following variables to connect the ESP32 to your local network:
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
The getSliderValues() function creates a JSON string with the current slider values.
String getSliderValues(){
sliderValues["sliderValue1"] = String(sliderValue1);
sliderValues["sliderValue2"] = String(sliderValue2);
sliderValues["sliderValue3"] = String(sliderValue3);
String jsonString = JSON.stringify(sliderValues);
return jsonString;
}
The notifyClients() function notifies all clients with the current slider values. Calling this function is what allows us to notify changes in all clients whenever you set a new position for a slider.
void notifyClients(String sliderValues) {
ws.textAll(sliderValues);
}
The handleWebSocketMessage(), as the name suggests, handles what happens when the server receives a message from the client via WebSocket protocol. We’ve seen in the JavaScript file, that the server can receive the getValues message or a message with the slider number and the slider value.
When it receives the getValues message, it sends the current slider values.
if (strcmp((char*)data, "getValues") == 0) {
notifyClients(getSliderValues());
}
If it receives another message, we check to which slider corresponds the message and update the corresponding duty cycle value. Finally, we notify all clients that a change occurred. Here’s an example for slider 1:
if (message.indexOf("1s") >= 0) {
sliderValue1 = message.substring(2);
dutyCycle1 = map(sliderValue1.toInt(), 0, 100, 0, 255);
Serial.println(dutyCycle1);
Serial.print(getSliderValues());
notifyClients(getSliderValues());
}
In the loop(), we update the duty cycle of the PWM channels to adjust the brightness of the LEDs.
void loop() {
ledcWrite(ledPin1, dutyCycle1);
ledcWrite(ledPin2, dutyCycle2);
ledcWrite(ledPin3, dutyCycle3);
ws.cleanupClients();
}
Upload Code and Files
After inserting your network credentials, save the code. Go to Sketch > Show Sketch Folder, and create a folder called data.
Inside that folder you should save the HTML, CSS and JavaScript files.
Then, upload the code to your ESP32 board. Make sure you have the right board and COM port selected. Also, make sure you’ve added your network credentials.
After uploading the code, you need to upload the files to the filesystem.
Press [Ctrl] + [Shift] + [P] on Windows or [⌘] + [Shift] + [P] on MacOS to open the command palette. Search for the Upload LittleFS to Pico/ESP8266/ESP32 command and click on it.
If you don’t have this option is because you didn’t install the filesystem uploader plugin. Check this tutorial.
Important: make sure the Serial Monitor is closed before uploading to the filesystem. Otherwise, the upload will fail.
When everything is successfully uploaded, open the Serial Monitor at a baud rate of 115200. Press the ESP32 EN/RST button, and it should print the ESP32 IP address.
Demonstration
Open a browser on your local network and paste the ESP32 IP address. You should get access to the web server page to control the brightness of the LEDs.
Move the sliders to control the brightness of the LEDs.
Open several tabs or connect to the web server using another device, and notice that the slider values update almost instantaneously whenever there’s a change.
You can watch the video demonstration:
Wrapping Up
In this tutorial, you’ve learned how to build a web server with the ESP32 that serves a web page with multiple sliders. The sliders allow you to control the brightness of LEDs connected to the ESP32. In addition, we’ve used the WebSocket protocol to communicate between the ESP32 and the clients.
We hope you had learned a lot from this tutorial. Let us know in the comments below if you successfully followed this tutorial and got the project working.
To learn more about building web servers with the ESP32, we really recommend taking a look at our eBook:
Learn more about the ESP32 with our resources:
Thank you for reading.
Hi,
I like your projects and tutorials but I’m not a web programmer and this is keeping me from experimenting :).
Other than App inventor is there another app you could propose me that would translate the graphics ptogramming to html code ?
Kind regards,
Mario
Hi.
I’m not familiar with any simulator of that kind.
It can be a good time to start learning HTML, CSS, and JavaScript.
You can check our Build Web Server eBook: https://randomnerdtutorials.com/build-web-servers-esp32-esp8266-ebook/.
We also have many free tutorials where we explain (not in as much detail as in the eBook) how the HTML, CSS, and JAvaScript works.
Regards,
Sara
Thanks Sara 🙂
Hi I saw your new project, I loaded the sketch and it is compiled correctly , I followed all your instructions but in the browser web page at the IP address of the ESP32 nothing is displayed. What do you suggest me to check.
Thanks
Massimo
Hi.
You’ve probably didn’t upload the files to the filesystem.
The files in the data folder.
Regards,
Sara
Make sure you upload the HTML, CSS, and JAvaScript files to your board.
Regards,
Sara
Ciao, ho scompattato il file zip che ho scaricato dal sito, lo sketch e i file HTML, CSS e JAvaScript sono nella cartella “data”. Inoltre dal monitor seriale sembra che vada tutto bene ed ottengo il messaggio seguente:
” SPIFFS mounted successfully ”
” Connecting to WiFi …192.168.1.64 ”
tuttavia la pagina web all’indirizzo 192.168.1.64 risulta vuota.
Hi Sara, ok now everything works, it was my first sketch with SPIFFS, I didn’t understand how to load the HTML, CSS and JAvaScript files in the ESP32 device, I thought they were loaded at compile time, now I used the function from the tools menu and everything went to its place.
Congratulations on your project.
Thanks
Regards
Massimo
// Web Server Root URL
server.on(“/”, HTTP_GET, [](AsyncWebServerRequest *request){
request->send(SPIFFS, “/index.html”, “text/html”);
});
server.on("/script.js", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(SPIFFS, "/script.js", "text/css");
});
I tried the schetch on two different ESP32 devices, but apart from the different IP address the result is the same
Great tutorial like always. I like the explanation of the code.
I have your book “Home Automation using ESP8266 eBook and video course” and learned a lot. If you ever revise it, I hope you include the ESP32. I don’t use the ESP8266 boards, just the ESP32 boards
Hi Anthony.
For the ESP32 boards, we have other eBooks.
Check all the eBooks here: https://randomnerdtutorials.com/courses/
Regards,
Sara
Hi, Is there any version of this tutorial without needing SPIFFS?
At the moment, we don’t have.
Regards,
Sara
Hello. First off, I was getting inconsistent results with the LEDs… Nothing happened until 50% then as I went further the LEDs would brighten, dim then brighten again.
I changed the mapped duty cycle from 1024 (10 bit) to 255 (8-bit) and everything worked properly. Not sure why you have 1024 (10 bit) setup for an LED? Am I missing somthing here?
As a side note: I wired an RGB LED instead of using discrete ones, and due to the fact that all I had was Common Anode, I had to modify the loop commands like so, to “reverse the effect” back to normal 🙂
void loop() {
ledcWrite(ledChannel1, 255-dutyCycle1); // -255 for Common Anode
ledcWrite(ledChannel2, 255-dutyCycle2); // -255 for Common Anode
ledcWrite(ledChannel3, 255-dutyCycle3); // -255 for Common Anode
Hi.
Thanks for pointing that out.
You’re right about the mapping (our mistake).
We’ll fix the code.
Regards,
Sara
Great tutorial, txs.
For I while now, I’ve been looking for a solution to control the brightness of standard 12V LED downlights in my home. Would I be able to use this for that purpose?
Of course you could…but you would need appropriate MOSFET drivers, and they truly have to be 12V LED modules. Many have built in drivers, and those probably won’t work.
Most down lights for homes in the US are not 12V. To use this project, there can be nothing in the light circuit but a resistor(s) and the LEDs themselves. You simple insert the MOSFET in line with the LED, and control the gate with the PWM from the ESP. The MOSFET used has to be a logic level gate, and I like the BTS 141 (low side switch) for use with 3.3v microprocessors. If there is any existing sort of driver module you would need to know if that is controllable with PWM….if so, (usually not) then you are good to go!
I was wondering how to add a password to the server to only let those with it to run the LED, motors etc.
Or simpler how would you load it into the ESP32 and then call the program. The password page can pop up first, but then how will it call the slider HTML/CSS/Jscript page???
Thank you for your thoughts.
Hi.
Take a look at this tutorial: https://randomnerdtutorials.com/esp32-esp8266-web-server-http-authentication/
Regards,
Sara
I could be mistaken but the article in the link below seems like a 1 on 1 copy of one of your articles https://gndtovcc.home.blog/2020/04/13/esp8266-web-server-using-spiffs-spi-flash-file-system-nodemcu/
I would give you both a complement for the information on the site, the books and the time you need for answer the questions. And the transparency of the answers.
😉
Thank you so much for your support 🙂
Regards,
Sara
Should this be slider or sliver?
void notifyClients(String sliverValues) {
ws.textAll(sliverValues);
}
Hi.
It works like that.
But, it should be sliderValues. We updated the code.
Thanks for noticing.
Regards,
sara
Hello Rui & Sara,
I have this up & running, & would like to be able to also modify the slider output internally in the ESP32. I tried adding the following to the loop, and I see the values are updated on the serial monitor, but not on the connected device webpage. Also, the Output to the LED connected to the ESP32 only varies when I move the slider. (Even tho I am changing the value of sliderValue1 in code)
How would I do this to make the LED variable either by the ESP directly, or by user input from a Web Page?
[code]
currentMillis = millis();
if((currentMillis - lastMillis) > interval)
{
tempSliderValue = sliderValue1.toInt();
if(tempSliderValue < 100)
{
tempSliderValue += 1;
}
else tempSliderValue = 0;
sliderValue1 = String(tempSliderValue);
notifyClients(getSliderValues());
Serial.print(tempSliderValue);
Serial.print(" ");
Serial.println(sliderValue1);
lastMillis = currentMillis;
}
[/code]
really like tutorials here..great job guys!!
Very Nice example, However I have many questions. How does one even began to
understand webservers from scratch. Some people can read through code as if it was straight reading. JavaScript I can follow somewhat lets say 50%; you add this to we socket and other stuff and now we have a challenge on our hands.
I am thinking starting with libraries would get me the format used possibly in the main files, but the time to get through this would be a life time?
I am assuming if you want a webserver; one just buys it and configures into the the system similar to ethernet stacks and USB stacks;
Phil
Hi Phill.
To learn about web servers with the ESP32/ESP8266 from scratch, you can get our eBook: “Build Web Servers with ESP32 and ESP8266” https://randomnerdtutorials.com/build-web-servers-esp32-esp8266-ebook/
Regards,
Sara
Have been trying this slider project several times with different board and different devices like phones, PC’s and pads. Uploaded the code and got the IP address. When putting the IP address in the browser of any device it comes up” This website is not secure and the “padlock” shows. Where have I got it wrong?
Hi
Adafruit HUZZAH32
arduino 1.8.13/teensyduino 1.53
MacOS 11.2.3
First I followed the tutorial ESP Websocket. That worked well and I could switch the button on and off.
Now I compiled and uploaded the code to the same board. It compiles and uploads fine, but in the browser I only see a blank webpage.
I uploaded the files in the data folder with “Datei hinzufügen” in the sketch menu.
What di I miss?
Hi.
When that happens it is usually because the files were not successfully uploaded to SPIFFS.
Regards,
Sara
Successfully completed project.
Thanks for a great tutorial, keep up the good work.
Great!
Thanks 😀
Hi Sara!
Question:
I did everything in VSCode and it works great! Do you know of a way to see the “Serial Output” in VSC? I normally switch to the Arduino IDE to view.
Thanks in advance and thank you for all you do and love all the projects!
Hi.
The icon that looks like a plug opens the serial monitor. See this picture: https://i1.wp.com/randomnerdtutorials.com/wp-content/uploads/2020/09/Platformio-VS-Code-Serial-Monitor-ESP32.png
You can also take a look at this tutorial: https://randomnerdtutorials.com/vs-code-platformio-ide-esp32-esp8266-arduino/
Regards,
Sara
Hi,
I am a noob on ESP32 & Arduino IDE. I have been trying few LED tutorials from this site and managed to successfully compile them on mu esp32 WROOM board.
First i tried single websocket slider.
Then multiple websoket slider.
Now, I want to start my original project.
To do that, I need to full fill below requirements.
Need a total of 8 slider (1. White, 2. Royal Blue, 3. Blue, 4, UV, 5. Violet, 6. green, 7 Cyan, 8 Red)
Need a on/off switch which will turn off or on all the channels.
Need timer option to turn on/off all the led’s with last slider settings.
Need to have the ability to input WiFi credentials from webpage so that everytime it doesn’t require hard coded WiFi credentials.
One master intensity slider to dim all the led’s. (say, blue is 80% & red is 60% in respective slider. When the master slider is reduced from 100% to 70% then in reality, the blue will become 56% & red will become 42%. But their respective slider will show 80% & 60% in the webpage.)
Components I Have:
1. ESP32
2. IRFZ44N Mosfet
3. RTC Module
4. 5v 40A Power Supply
5. 57 pcs 3w high power LED
Please guide me through the process or suggest me tutorials to understand more.
Thank You
Hi.
Just search our web server examples. We have many examples that might be useful:
– Example for wi-fi manager: https://randomnerdtutorials.com/esp32-status-indicator-sensor-pcb/
– How to use websockets: https://randomnerdtutorials.com/esp32-websocket-server-arduino/
– Control with timers: https://randomnerdtutorials.com/esp32-esp8266-web-server-timer-pulse/
You can check all our ESP32 projects here: https://randomnerdtutorials.com/projects-esp32/
Regards,
Sara
Thank you for the reply. I have managed to create 9 channel pwm controller using this tutorial.
Now, I want to add a on off switch for one of the channel.
Please assist me how i can do it.
Problem:
Though everything seems fine, but every time i unplug the ESP32 from power & re-power the device, all the slider goes back to “0%”. Is there any way to keep the last slider settings and power on the device with last slider settings?
Hi.
To keep the last settings you need to save your variables in the Flash memory every time they change and then, read all variable values when the ESP32 restarts.
To do that, you can save your data using EEPROM, the Preferences library, or create a txt file in the filesystem (SPIFFS).
Here are some resources:
– https://randomnerdtutorials.com/install-esp32-filesystem-uploader-arduino-ide/
– https://randomnerdtutorials.com/esp32-save-data-permanently-preferences/
– https://randomnerdtutorials.com/esp32-flash-memory/
I hope this helps.
Regards,
Sara
11:21:59.156 -> Core 0 register dump:
11:21:59.156 -> PC : 0x400d2967 PS : 0x00060530 A0 : 0x800d29ef A1 : 0x3ffb4ec0
11:21:59.156 -> A2 : 0x00000000 A3 : 0x3ffd12c8 A4 : 0x00000000 A5 : 0x3ffd2a6a
11:21:59.156 -> A6 : 0x00000014 A7 : 0x3ffb4460 A8 : 0x8012f842 A9 : 0x3ffb4eb0
11:21:59.156 -> A10 : 0x0000ffff A11 : 0x00000000 A12 : 0x00000005 A13 : 0x00000020
11:21:59.156 -> A14 : 0x00000020 A15 : 0x00000000 SAR : 0x00000019 EXCCAUSE: 0x0000001c
11:21:59.156 -> EXCVADDR: 0x0000001c LBEG : 0x4000c2e0 LEND : 0x4000c2f6 LCOUNT : 0xffffffff
11:21:59.202 ->
11:21:59.202 -> ELF file SHA256: 0000000000000000
11:21:59.202 ->
11:21:59.202 -> Backtrace: 0x400d2967:0x3ffb4ec0 0x400d29ec:0x3ffb4ef0 0x4012da81:0x3ffb4f10 0x4012e51a:0x3ffb4f30 0x40134777:0x3ffb4f50 0x40138ebe:0x3ffb4f80 0x40127217:0x3ffb4fa0 0x40089932:0x3ffb4fd0
11:21:59.202 ->
11:21:59.202 -> Rebooting…
11:21:59.202 -> ets Jun 8 2016 00:22:57
11:21:59.202 ->
11:21:59.202 -> rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
11:21:59.202 -> configsip: 0, SPIWP:0xee
11:21:59.202 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
11:21:59.202 -> mode:DIO, clock div:1
11:21:59.202 -> load:0x3fff0018,len:4
11:21:59.202 -> load:0x3fff001c,len:1044
11:21:59.250 -> load:0x40078000,len:10124
11:21:59.250 -> load:0x40080400,len:5856
11:21:59.250 -> entry 0x400806a8
11:21:59.627 -> SPIFFS mounted successfully
11:21:59.768 -> Connecting to WiFi …..192.168.0.234
11:22:02.749 -> Đang chạy ở loop1WebSocket client #1 connected from 192.168.0.3
11:22:06.749 -> Đang chạy ở loop2
11:22:08.766 -> Đang chạy ở loop3
11:22:10.172 -> assertion “new_rcv_ann_wnd <= 0xffff” failed: file “/home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/lwip/lwip/src/core/tcp.c”, line 779, function: tcp_update_rcv_ann_wnd
11:22:10.172 -> abort() was called at PC 0x400f918f on core 0
11:22:10.172 ->
11:22:10.172 -> ELF file SHA256: 0000000000000000
11:22:10.219 ->
11:22:10.219 -> Backtrace: 0x400886a4:0x3ffb4ed0 0x40088921:0x3ffb4ef0 0x400f918f:0x3ffb4f10 0x4012a6da:0x3ffb4f40 0x4012a761:0x3ffb4f60 0x400d2246:0x3ffb4f80 0x401271f8:0x3ffb4fa0 0x40089932:0x3ffb4fd0
11:22:10.219 ->
11:22:10.219 -> Rebooting…
11:22:10.219 -> ets Jun 8 2016 00:22:57
11:22:10.219 ->
11:22:10.219 -> rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
11:22:10.219 -> configsip: 0, SPIWP:0xee
11:22:10.219 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
11:22:10.219 -> mode:DIO, clock div:1
11:22:10.219 -> load:0x3fff0018,len:4
11:22:10.219 -> load:0x3fff001c,len:1044
11:22:10.219 -> load:0x40078000,len:10124
11:22:10.219 -> load:0x40080400,len:5856
11:22:10.266 -> entry 0x400806a8
11:22:10.640 -> SPIFFS mounted successfully
You are getting this error while running
Hi.
Did you change anything on the code?
What board are you using?
Regards
Sara
Hi, I have identified two problems in the code.
The script.js file was not read and the script reference should be document.getElementById(“sliderValue”+ (i+1).toString()).value = myObj[key];
// Web Server Root URL
server.on(“/”, HTTP_GET, [](AsyncWebServerRequest *request){
request->send(SPIFFS, “/index.html”, “text/html”);
});
server.on(“/script.js”, HTTP_GET, [](AsyncWebServerRequest *request){
request->send(SPIFFS, “/script.js”, “text/js”);
});
Hi,
I try to add additional slider and port from 10 to 16 and it didn’t work…
Slides from 1-9 works..but from 10-16 not working..
Can you help me with this?
Your problem seems to lie in these lines:
if (message.indexOf(“1s”) >= 0) {
sliderValue1 = message.substring(2);
The message is of the form “1s123” but in the case of more then 9 sliders becomes “13s123” and then message.substring( 2) gives “s123” wich is no number. So after:
if (message.indexOf(“10s”) >= 0) { you should write:
sliderValue1 = message.substring(3);
Maybe this is the problem:
if (message.indexOf(“1s”) >= 0) {
sliderValue1 = message.substring(2);
the message is of the form “1s123” so the substring(2) is “123”
in the case of message “10s123” the substring (2) reads “s123” wich us no number.
if you write:
if (message.indexOf(“10s”) >= 0) {
sliderValue1 = message.substring(3); then it reads “123”.
So for sliders above 9 you should write (3) instead pof (2).
There is also a problem in the script.js:
var sliderNumber = element.id.charAt(element.id.length-1);
this cannot make a slider identification greater then 9 because then there must be 2 characters.
Sorry, but i have no idea how to solve this.
You would call the first slider “Slider01” rather than “Slider1” – and then tweak the code “length-2” – something like that …
I got it working for 18 sliders, numbered from 101 to 118. Slider 1 becomes 101, 2 becomes 102 … and so on until 18 becomes 118. So all numbers are of the same lenght as a string.
In the ino .
if (message.indexOf(“101s”) >= 0) {
sliderValue101 = message.substring(4);
dutyCycle101 = map(sliderValue101.toInt(), 0, 100, 0, 255);
instead of substring(2)
The message of the form “1s55” is now “101s55”, so the numbers start at substring(4), not at substring(2)
I tested on a board with a blue LED connected to the 3.3 V powerline on GPIO16. so
i modified the line for slider 103:
if (message.indexOf(“103s”) >= 0) {
sliderValue103 = message.substring(4);
dutyCycle103 = 255 – map(sliderValue103.toInt(), 0, 100, 0, 255);
In script.js:
function updateSliderPWM(element) {
console.log(element);
var sliderNumber = 100 * element.id.charAt(element.id.length-3)
+ 10 * element.id.charAt(element.id.length-2)
+ 1 * element.id.charAt(element.id.length-1);
var sliderValue = document.getElementById(element.id).value;
document.getElementById(“sliderValue”+sliderNumber).innerHTML = sliderValue;
console.log(sliderValue);
websocket.send(sliderNumber+”s”+sliderValue.toString());
}
This way it could format slidernumbers from 100 to 999, but we use only 101 until 118. It looks inefficient, but it is effective.
Also in script.js:
function onMessage(event) {
console.log(event.data);
var myObj = JSON.parse(event.data);
var keys = Object.keys(myObj);
for (var i = 0; i < keys.length; i++){
var key = keys[i];
document.getElementById(key).innerHTML = myObj[key];
document.getElementById(“slider”+ (i+101).toString()).value = myObj[key];
}
}
The counter i will be from 0 until 17, so the it generates “slider101” until “slider118”
In styles.css i changed max-width from 700px to 1366px and minmax( from 200px to 190px, so 18 sliders fit on a laptop screen of 1366 by 768 pixels as 3 rows of 6 columns.
I sure hope i did not forget anything. I can provide the files.
Sara, Please remove my other posts on this question.
Hello,
What a great tutorial, but I still have a question.
I want to control three different ESP32’s at the same time with 3 different IP addresses or three ESP32s (one ESP32 per slider) from one web browser.
Is this possible and if so how.
You can only have one ESP32 hosting the website – you would need to send the information between the ESP32s after the host has received the request from the front end. Use ESPNOW to communicate between the ESPs.
No code changes made, everything works fine. But, seems values are inverted. When the ESP32 is initialized, all LEDs are on. Sliders in the web interface show 0%. As I slide them to 100% (full brightness), the corresponding LED dims.
Hi.
What board are you using?
I’ve just tried the project again and everything seems to be working as expected.
Regards,
Sara
Maybe you have connected your led’s against the positive supply line instead of the ground line.
If the led’s are connected to the positive 3,3V or 5V line instead of ground line they work inverted. Sometimes with the led on the board you can’t change this behaviour. A solution can be to modify the corresponding line in the program like:
dutyCycle3 = 255 – map(sliderValue3.toInt(), 0, 100, 0, 255);
At first after you connect to the webserver it looks not right, but after a few clicks on the corresponding sliders it shows right.
I would like to use this project but to control the servos using PCA9685 – 16-channel 12-bit PWM I2C servo driver – Adafruit 815. How can it be done?
Is it possible to use this project to control servos? I want to connect the servos to the PCA9685 driver.
In the HTLM code there is onchange=”updateSliderPWM(this)”, the response changes after releasing the slider. If you change into oninput=”updateSliderPWM(this)” you get response while you move the slider.
Beautiful tutorial !!!!
Great project and all works fine, thank you. I wanted to add a ON/OFF button. All is OK on the html page, I can click on the button but I need to close my page after this because no more connection to the server… Any idea ?
Without the code it is difficult to say what causes your problem.
Hi Rui and Sara,
This is brilliant code – easy to follow – ASYCN is the way to go – and your clever indexing of the events being received at the front end is genius level coding. It has allowed me to get passed the impasse that I was having – thank you.
I have just one thought – My NodeMCU crashes if the sliders are fiddled with too much – the websocket gets overloaded with requests from the front end and crashes the NodeMCU.
My limited knowledge of this can’t solve this – I was wondering whether you can think of any front end coding that could throttle back the slider changes – to stop the NodeMCU from crashing – Do you think that is an easy fix ?
Hi, I followed all the steps, I’m getting the IP on serial monitor, but when I open it, it says page can’t be found.
Please help me resolving this error
Hi.
You probably didn’t upload the files to the filesystem.
Regards,
Sara
hi, i have a compil error:
D:\arduino_prog_lib\libraries\ESPAsyncWebServer-master\src/AsyncWebSocket.cpp:1272: undefined reference to
SHA1Init'
mbedtls_md5_starts’and
D:\arduino_prog_lib\libraries\ESPAsyncWebServer-master\src/WebAuthentication.cpp:73: undefined reference to
Can you help me resolving this error. (data is in folder sketch).
thanks
Hi.
Due to an update of the ESP32, you might need to replace the platform to [email protected] instead espressif32 in the platformio.ini file.
Let me know if this solves the issue.
Regards,
Sara
HI, i have updated my esp32 lib on 1.18.13(1.0.1) ide and that works now, but i don’t know why!
i have installed ide 2.1.0 before and it’s at this time what this mistake is arrived.
Probably, instalation of 2.1.0 arduino have changed something, but where?
thanks for your respond.
Hi, I just ran into the same problem and your suggestion created a different issue for me.
This is my original platform.ini file
[env:esp32-s2-saola-1]
platform = espressif32
board = esp32-s2-saola-1
framework = arduino
upload_port = /dev/cu.usbserial-21420
monitor_speed = 115200
lib_deps = ESP Async WebServer
arduino-libraries/Arduino_JSON @ 0.1.0
When I change the platform I get:
Resolving esp32-s2-saola-1 dependencies…
Already up-to-date.
Updating metadata for the vscode IDE…
Error: Processing esp32-s2-saola-1 (platform: [email protected]; board: esp32-s2-saola-1; framework: arduino)
Verbose mode can be enabled via
-v, --verbose
optionCONFIGURATION: https://docs.platformio.org/page/boards/espressif32/esp32-s2-saola-1.html
PLATFORM: Espressif 32 (3.5.0) > Espressif ESP32-S2-Saola-1
HARDWARE: ESP32S2 240MHz, 320KB RAM, 4MB Flash
DEBUG: Current (esp-prog) External (esp-prog, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd, olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa)
PACKAGES:
– framework-arduinoespressif32 @ 3.10006.210326 (1.0.6)
– tool-esptoolpy @ 1.30100.210531 (3.1.0)
– toolchain-riscv-esp @ 1.80400.0 (8.4.0)
– toolchain-xtensa32s2 @ 1.80400.210211 (8.4.0)
Error: This board doesn’t support arduino framework!
========================== [FAILED] Took 0.23 seconds ==========================
Try to select a different ESP323 board like:
board = esp32doit-devkit-v1
And see if that makes a difference.
Regards,
Sara
Followup on my own issue. I fixed it by editing the following.
lib_deps =
me-no-dev/AsyncTCP @ ^1.1.1
https://github.com/me-no-dev/ESPAsyncWebServer.git
arduino-libraries/Arduino_JSON @ 0.1.0
As per the following suggestions.
https://github.com/me-no-dev/ESPAsyncWebServer/issues/1151
Lot of work to port it to 8266,
I have error on case:
case WS_EVT_DATA:
the error is: exit status 1
jump to case label
Hi.
What version of the ESP32 do you have installed?
Fo to Tools > Board > Boards Manager and search for ESP32. Check the version. You may need to update.
Regards,
Sara
Hello,
I just has one question, I uploaded the code (it uploaded successfully), I proceeded to check the serial moniter and it said the spiffs were mounted successfully and the ESP32 was connected to the internet, but when I typed in the IP address into Google Chrome it says, “This (ip address) page can’t be found No webpage was found for the web address: http://(Address)
HTTP ERROR 404.”
I hope you have an answer, Emanuel
Hi.
You probably forgot to upload the files to the filesystem.
Read the section “Upload Code and Files” carefully.
Regards,
Sara
ESP32 is cyclically overloaded/
Tries to connect to WI FI and goes into reboot
What is exactly the error that you get?
Hi, great Work, do You know the Code for make Memory of the last states of the Sliders ? After Power off all its gone.. it would be nice if there are some memory Function for the latest Settings. And maeby also a Button at the End of the Page for close the Window and disconnect the Wifi Connection. Thx for Feedback and Your Effort.
Just a quick question. I have everything working, except my LED’s keep flickering. Rest is working fine. I’m using the ESP32-WROOM-32. Any suggestions?
Same here 🙁
Hi please remove the previous comment.
The answer for Bert Jager is:
Switch to the other GND Pin.
Regards,
Marko
Hello Sara,
I am working on a simple multiple slider project and remembered that you have this example.
So I tried to run it and ran into the above mentioned compile issues which I solved meanwhile.
Now I am getting continuous reboots with following message:
E (15576) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (15576) task_wdt: – async_tcp (CPU 0/1)
E (15576) task_wdt: Tasks currently running:
E (15576) task_wdt: CPU 0: IDLE0
E (15576) task_wdt: CPU 1: loopTask
E (15576) task_wdt: Aborting.
abort() was called at PC 0x4014af04 on core 0
The only thing I changed from your code are the credentials and the pins assigned to PWM
I am using an ESP32 D1 mini board.
Any idea what this could be?
Best regards,
Roger
That is interesting. The problem disappeared after disconnecting the board from USB.
Don’t ask me why. I used exactly the same code.
So you can close this issue.
Best regards,
Roger
Hi Sara,
I have implemented this example on a project, using 4 sliders representing colours (R, G, B, W) and a U8G2 OLED screen to display the slider values. The problem is that the client sends a flood of messages when moving the sliders, which causes the OLED to continuously refresh while parsing each message received.
I have fixed the issue by adding a ‘mouseup’ event listener to the slider. However, this is only for test purposes. Since the client code will be written by a third party in the final project, and the ‘mouseup’ solution may not be used, do you have any suggestions on ways to make the ESP decide when to refresh the screen, so that it would look smoother?
Best regards,
Mike
Hi Sara,
Sorry to disturb you, but I have a tricky problem I am not able to solve.
I had this code working a few years ago, but when I try it to compile this year this always failes. That is on Arduino 1.8.19 and also on Arduino 2.0.x and higher. I have tried this on various boards, but I get always the same errors.
I got the impression the error is in <ESPAsyncWebServer.h>
So I made a sketch like this:
#include <ESPAsyncWebServer.h>
void setup() {
// put your setup code here, to run once:
}
void loop() {
// put your main code here, to run repeatedly:
}
And on verify it gives this error:
Arduino: 1.8.19 (Windows 10), Board: “ESP32 Dev Module, Disabled, Disabled, Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS), 240MHz (WiFi/BT), QIO, 80MHz, 4MB (32Mb), 921600, Core 1, Core 1, None, Disabled, Disabled”
C:\Arduino-ESP32\libraries\ESPAsyncWebServer-master\src\AsyncWebSocket.cpp: In member function ‘IPAddress AsyncWebSocketClient::remoteIP()’:
C:\Arduino-ESP32\libraries\ESPAsyncWebServer-master\src\AsyncWebSocket.cpp:832:28: error: call of overloaded ‘IPAddress(unsigned int)’ is ambiguous
832 | return IPAddress(0U);
| ^
In file included from C:\Users\marius\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.7\cores\esp32/Arduino.h:196,
from C:\Arduino-ESP32\libraries\ESPAsyncWebServer-master\src\AsyncWebSocket.cpp:21:
C:\Users\marius\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.7\cores\esp32/IPAddress.h:115:3: note: candidate: ‘IPAddress::IPAddress(const ip_addr_t*)’
115 | IPAddress(const ip_addr_t *addr);
| ^~~~~~~~~
C:\Users\marius\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.7\cores\esp32/IPAddress.h:73:3: note: candidate: ‘IPAddress::IPAddress(const IPAddress&)’
73 | IPAddress(const IPAddress &address);
| ^~~~~~~~~
C:\Users\marius\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.7\cores\esp32/IPAddress.h:72:3: note: candidate: ‘IPAddress::IPAddress(const char*)’
72 | IPAddress(const char *address);
| ^~~~~~~~~
C:\Users\marius\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.7\cores\esp32/IPAddress.h:69:3: note: candidate: ‘IPAddress::IPAddress(const uint8_t*)’
69 | IPAddress(const uint8_t *address);
| ^~~~~~~~~
C:\Users\marius\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.7\cores\esp32/IPAddress.h:67:3: note: candidate: ‘IPAddress::IPAddress(uint32_t)’
67 | IPAddress(uint32_t address);
| ^~~~~~~~~
Multiple libraries were found for “WiFi.h”
Used: C:\Users\marius\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.7\libraries\WiFi
Not used: C:\Program Files (x86)\Arduino\libraries\WiFi
Multiple libraries were found for “AsyncTCP.h”
Used: C:\Arduino-ESP32\libraries\AsyncTCP
Not used: C:\Arduino-ESP32\libraries\AsyncTCP-master
exit status 1
Error compiling for board ESP32 Dev Module.
Do you get the same errors or do you know where to get a better <ESPAsyncWebServer.h>?
Thank you for your help.
Hi.
What version of the library are you running?
Please use the library mentioned in our URL.
Regards,
Sara
Hi Sara,
I think I use version 3.0.7 as is shown in the errors:
C: Users\marius\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.7\cores\esp32
I got just https://github.com/me-no-dev/ESPAsyncWebServer, but it makes no difference.
Could please specify the URL you mentioned?
Regards,
Marius
Hi.
How did you install the libraries?
The issue seems with the AsyncTCP we server:
Multiple libraries were found for “AsyncTCP.h”
Used: C:\Arduino-ESP32\libraries\AsyncTCP
Not used: C:\Arduino-ESP32\libraries\AsyncTCP-master
Go to those paths and delete the AsyncTCP libraries folder.
Then, install again like this:
1) Download the library by going to this link: https://github.com/me-no-dev/AsyncTCP/archive/refs/heads/master.zip
2) install the Library in the Arduino IDE via ZIP folder. Sketch > Include Library > Add .ZIP folder and select the newly dowloaded folder.
Try to compile the code again.
Let me know if this solves the issue.
Regards.
Sara
Hallo Sara,
It wasn’t the AsyncTCP library but the ESAsybcWebServer-master that made the troubles.
I removed C:\Arduino-ESP32-libraries\ESPAsyncWebServer-master and installed the library again as you suggested with: Sketch>Include Library>Add .ZIP folder and selected C:\Arduino-ESP32-libraries\ESPAsyncWebServer-master.zip.
This folder I had downloaded yesterday. I had the .zip file unpacked on the spot, but that is wrong.
Thank you for your help.
Regards,
Marius
Is everything working as expected now?
The compilation is now working as expected.
Thanks again!
Regards,
Marius