In this guide, you’ll learn how to create a WebSocket server with the ESP8266 NodeMCU board to display sensor readings on a web page. Whenever the ESP8266 has new readings available, the web page is updated automatically without the need to manually refresh it.
To learn more about building web servers with the ESP32 and ESP8266 from scratch, check our eBook: Build Web Servers with the ESP32 and ESP8266.
Table of Contents
Throughout this tutorial, we’ll cover the following main topics:
- Introducing WebSocket Protocol
- Install Required Libraries and Plugins
- Building the Web Server Project: Display Sensor Readings
We have a similar tutorial for the ESP32 board: ESP32 WebSocket Server: Display Sensor Readings
Introducing WebSocket Protocol
A WebSocket is a persistent connection between a client and a server that allows bidirectional communication between both parties using a TCP connection. This means you can send data from the client to the server and from the server to the client at any given time.
The client establishes a WebSocket connection with the server through a process known as WebSocket handshake. The handshake starts with an HTTP request/response, allowing servers to handle HTTP connections as well as WebSocket connections on the same port. Once the connection is established, the client and the server can send WebSocket data in full duplex mode.
Using the WebSockets protocol, the server (ESP8266 board) can send information to the client or to all clients without being requested. This also allows us to send information to the web browser when a change occurs.
This change can be something that happened on the web page (you clicked a button) or something that happened on the ESP8266 side like pressing a physical button on a circuit, or new sensor readings available.
Learn how to control the ESP8266 outputs via WebSocket protocol: ESP8266 WebSocket Server: Control Outputs (Arduino IDE).
Project Overview
Here’s the web page we’ll build for this project.
- We’ll create a web page that displays temperature, humidity, and pressure.
- The web page displays the latest sensor readings when you open or refresh the web page.
- The sensor readings update automatically whenever there’s a new reading available on the ESP8266 without the need to refresh the webpage.
- The web server works perfectly on multiple clients (multiple web browser tabs on the same device or different devices).
How does it work?
- The ESP hosts a web server that displays a web page with three cards for the sensor readings.
- When you open the webpage, it sends a message (getReadings) to the ESP via WebSocket protocol. The server (ESP) receives that message. When that happens, it gets new readings from the sensors and sends them back to the client (web browser), also via web socket protocol. This way, whenever you open a new tab, it always shows the current and updated values.
- Every 30 seconds, the ESP gets new readings and sends them to all connected clients (all web browser tabs opened) via WebSocket protocol. The client receives that message and displays the readings on the web page.
Prerequisites
Before proceeding with this tutorial, make sure you check all the following prerequisites.
1) Parts Required
To follow this project you need:
- ESP8266 Board – read ESP8266 Boards Review and Comparison
- BME280 sensor module – check the BME280 getting started guide with the ESP32
- Breadboard
- Jumper wires
For this example, we’ll use a BME280 sensor, but you can use any other sensor you’re familiar with.
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 ESP8266 Boards Add-on
We’ll program the ESP8266 using Arduino IDE. So, you must have the ESP8266 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 ESP8266:
3) Filesystem Uploader Plugin
To upload the HTML, CSS, and JavaScript files needed to build this project to the ESP8266 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)
- Adafruit_BME280 (Arduino Library Manager)
- ESPAsyncWebServer (.zip folder)
- ESPAsyncTCP (.zip folder)
You can install the first two libraries using the Arduino Library Manager. Go to Sketch > Include Library > Manage Libraries and search for the library name.
The ESPAsyncWebServer and ESPAsynTCP 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 ESP8266 using PlatformIO, you should add the following lines to the platformio.ini file to include the libraries (also change the Serial Monitor speed to 115200):
monitor_speed = 115200
lib_deps = ESP Async WebServer
arduino-libraries/Arduino_JSON @ 0.1.0
adafruit/Adafruit BME280 Library @ ^2.1.0
adafruit/Adafruit Unified Sensor @ ^1.1.4
Building the Circuit
To exemplify how to display sensor readings on a web server with the ESP8266, we’ll send sensor readings from a BME280 sensor to the browser. So, you need to wire a BME280 sensor to your ESP8266. You can also use any other sensor you’re familiar with.
Schematic Diagram
We’re going to use I2C communication with the BME280 sensor module. For that, wire the sensor to the default ESP8266 SCL (GPIO 5) and SDA (GPIO 4) pins, as shown in the following schematic diagram.
Recommended reading: ESP8266 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: to get the sensor readings and handle the web server;
- index.html: to define the content of the web page to display the sensor readings;
- style.css: to style the web page;
- script.js: to program the behavior of the web page—handle what happens when you open the web page and display the readings 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 ESP8266 filesystem (LittleFS).
You can download all project files:
HTML File
Copy the following to the index.html file.
<!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>SENSOR READINGS (WEBSOCKET)</h1>
</div>
<div class="content">
<div class="card-grid">
<div class="card">
<p class="card-title"> Temperature</p>
<p class="reading"><span id="temperature"></span> °C</p>
</div>
<div class="card">
<p class="card-title"> Humidity</p>
<p class="reading"><span id="humidity"></span> %</p>
</div>
<div class="card">
<p class="card-title"> Pressure</p>
<p class="reading"><span id="pressure"></span> hpa</p>
</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
We won’t go into much detail about the content of the HTML file. Just the relevant parts.
The following lines display a card for the temperature.
<div class="card">
<p class="card-title"><i class="fas fa-thermometer-threequarters" style="color:#059e8a;"></i> Temperature</p>
<p class="reading"><span id="temperature"></span> °C</p>
</div>
The temperature will show up in the following paragraph between the <span> tags. Notice that you need a unique id for that HTML tag so that later we know how to refer to this HTML element. In this case, the unique id is temperature.
<span id="temperature"></span>
We do a similar procedure for the humidity and pressure. The unique ids for the HTML element where we’ll display the humidity and pressure are humidity and pressure.
<div class="card">
<p class="card-title"> Humidity</p>
<p class="reading"><span id="humidity"></span> %</p>
</div>
<div class="card">
<p class="card-title"> Pressure</p>
<p class="reading"><span id="pressure"></span> hpa</p>
</div>
CSS File
Copy the following to the style.css file. Feel free to change it to make the web page look as you wish. We won’t explain how the CSS for this web page works because it is not relevant for this tutorial.
html {
font-family: Arial, Helvetica, sans-serif;
display: inline-block;
text-align: center;
}
h1 {
font-size: 1.8rem;
color: white;
}
.topnav {
overflow: hidden;
background-color: #0A1128;
}
body {
margin: 0;
}
.content {
padding: 50px;
}
.card-grid {
max-width: 800px;
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;
}
.reading {
font-size: 1.2rem;
color: #1282A2;
}
JavaScript File
Copy the following to the script.js file.
var gateway = `ws://${window.location.hostname}/ws`;
var websocket;
// Init web socket when the page loads
window.addEventListener('load', onload);
function onload(event) {
initWebSocket();
}
function getReadings(){
websocket.send("getReadings");
}
function initWebSocket() {
console.log('Trying to open a WebSocket connection…');
websocket = new WebSocket(gateway);
websocket.onopen = onOpen;
websocket.onclose = onClose;
websocket.onmessage = onMessage;
}
// When websocket is established, call the getReadings() function
function onOpen(event) {
console.log('Connection opened');
getReadings();
}
function onClose(event) {
console.log('Connection closed');
setTimeout(initWebSocket, 2000);
}
// Function that receives the message from the ESP32 with the readings
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];
}
}
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 sensor readings;
- uses the response to update the sensor readings 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 is open, we’ll call the getReadings function.
function onOpen(event) {
console.log('Connection opened');
getReadings();
}
The getReadings() function sends a message to the server getReadings to get the current sensor readings. Then, we must handle what happens when we receive that message on the server side (ESP8266).
function getReadings(){
websocket.send("getReadings");
}
We handle the messages received via WebSocket protocol on the onMessage() function.
// Function that receives the message from the ESP8266 with the readings
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];
}
}
The server sends the readings in JSON format, for example:
{
temperature: 20;
humidity: 50;
pressure: 1023;
}
The onMessage() function simply goes through all the key values (temperature, humidity, and pressure) and places them in the corresponding places on the HTML page. In this case, the keys have the same name as the ids we’ve defined on the HTML page. So, we can simply do something like this:
for (var i = 0; i < keys.length; i++){
var key = keys[i];
document.getElementById(key).innerHTML = myObj[key];
}
Code for ESP8266 WebSocket Server (Sensor Readings)
Copy the following code to your Arduino IDE.
/*********
Rui Santos
Complete instructions at https://RandomNerdTutorials.com/esp8266-nodemcu-websocket-server-sensor/
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 <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include "LittleFS.h"
#include <Arduino_JSON.h>
#include <Adafruit_BME280.h>
#include <Adafruit_Sensor.h>
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
// Create a WebSocket object
AsyncWebSocket ws("/ws");
// Json Variable to Hold Sensor Readings
JSONVar readings;
// Timer variables
unsigned long lastTime = 0;
unsigned long timerDelay = 30000;
// Create a sensor object
Adafruit_BME280 bme; // BME280 connect to ESP32 I2C (GPIO 21 = SDA, GPIO 22 = SCL)
// Init BME280
void initBME(){
if (!bme.begin(0x76)) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
}
// Get Sensor Readings and return JSON object
String getSensorReadings(){
readings["temperature"] = String(bme.readTemperature());
readings["humidity"] = String(bme.readHumidity());
readings["pressure"] = String(bme.readPressure()/100.0F);
String jsonString = JSON.stringify(readings);
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 sensorReadings) {
ws.textAll(sensorReadings);
}
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;
//String message = (char*)data;
// Check if the message is "getReadings"
//if (strcmp((char*)data, "getReadings") == 0) {
//if it is, send current sensor readings
String sensorReadings = getSensorReadings();
Serial.print(sensorReadings);
notifyClients(sensorReadings);
//}
}
}
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);
initBME();
initWiFi();
initFS();
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() {
if ((millis() - lastTime) > timerDelay) {
String sensorReadings = getSensorReadings();
Serial.print(sensorReadings);
notifyClients(sensorReadings);
lastTime = millis();
}
ws.cleanupClients();
}
How the Code Works
Continue reading to learn how the code works, or skip to the demonstration section.
Including Libraries
The Adafruit_Sensor and Adafruit_BME280 libraries are needed to interface with the BME280 sensor.
#include <Adafruit_BME280.h>
#include <Adafruit_Sensor.h>
The ESP8266WiFi, ESPAsyncWebServer, and ESPAsyncTCP libraries are used to create the web server.
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
We’ll save the HTML, CSS, and JavaScript files on the ESP8266 filesystem, so we also need to include the LittleFS.h library.
#include "LittleFS.h"
To create JSON objects, we’ll use the Arduino_JSON library.
#include <Arduino_JSON.h>
Network Credentials
Insert your network credentials in the following variables, so that the ESP8266 can connect to your local network using Wi-Fi.
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
AsyncWebServer and AsyncWebSocket
Create an AsyncWebServer object on port 80.
AsyncWebServer server(80);
The following line creates a new websocket object on /ws.
// Create a WebSocket object
AsyncWebSocket ws("/ws");
Timer Variables
The following variables are used to create timers in our code. In our case, we’ll send sensor readings to the client via WebSocket protocol every 30000 milliseconds (30 seconds). You can change the timerDelay variable to any other value that makes sense for your project.
// Timer variables
unsigned long lastTime = 0;
unsigned long timerDelay = 30000;
Initializing the BME280 Sensor
The following line creates an Adafruit_BME280 object to refer to the sensor called bme.
// Create a sensor object
Adafruit_BME280 bme;
The initBME() function initializes the sensor. It will be called later in the setup().
// Init BME280
void initBME(){
if (!bme.begin(0x76)) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
}
Getting Sensor Readings (JSON String)
The getSensoreadings() function creates a JSON string with the current sensor readings.
// Get Sensor Readings and return JSON object
String getSensorReadings(){
readings["temperature"] = String(bme.readTemperature());
readings["humidity"] = String(bme.readHumidity());
readings["pressure"] = String(bme.readPressure()/100.0F);
String jsonString = JSON.stringify(readings);
return jsonString;
}
Initializing the Filesystem
The initFS() function initializes LittleFS, the ESP8266 filesystem we’re using in this project to save the HTML, CSS, and Javascript files.
// Initialize LittleFS
void initFS() {
if (!LittleFS.begin()) {
Serial.println("An error has occurred while mounting LittleFS");
}
else{
Serial.println("LittleFS mounted successfully");
}
}
Initializing Wi-Fi
The following function initializes Wi-Fi and connects to your network using the credentials you used previously. This function will be called later in the setup().
// 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());
}
Notifying all Clients Via WebSocket
The notifyClients() function notifies all clients with the current sensor readings. Calling this function is what allows us to notify changes in all clients whenever we get new sensor readings (every 30 seconds).
void notifyClients(String sensorReadings) {
ws.textAll(sensorReadings);
}
Handling WebSocket Messages
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 getReadings message.
When the ESP8266 receives the getReadings message, it sends the current sensor readings.
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;
String message = (char*)data;
// Check if the message is "getReadings"
if (strcmp((char*)data, "getReadings") == 0) {
// if it is, send current sensor readings
String sensorReadings = getSensorReadings();
Serial.print(sensorReadings);
notifyClients(sensorReadings);
}
}
}
Handling WebSocket Events
The onEvent() function handles other WebSocket events.
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;
}
}
Initializing WebSocket Protocol
The initWebSocket() function initializes the WebSocket protocol.
void initWebSocket() {
ws.onEvent(onEvent);
server.addHandler(&ws);
}
setup()
In the setup(), we initialize the Serial Monitor, the BME280 sensor, Wi-Fi, the filesystem, and the WebSocket protocol by calling the functions we’ve created previously.
Serial.begin(115200);
initBME();
initWiFi();
initSPIFFS();
initWebSocket();
The following lines will serve the index.html and the other referenced static files saved on SPIFFS (style.css and script.js) when you access the web server.
// Web Server Root URL
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
request->send(SPIFFS, "/index.html", "text/html");
});
server.serveStatic("/", SPIFFS, "/");
Finally, start the server.
// Start server
server.begin();
loop()
In the loop(), we get and send new sensor readings every 30000 milliseconds (30 seconds).
void loop() {
if ((millis() - lastTime) > timerDelay) {
String sensorReadings = getSensorReadings();
Serial.print(sensorReadings);
notifyClients(sensorReadings);
lastTime = millis();
}
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 place the HTML, CSS, and JavaScript files.
Then, upload the code to your ESP8266 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. Go to Tools > ESP8266 LittleFS Data Upload and wait for the files to be uploaded.
When everything is successfully uploaded, open the Serial Monitor at a baud rate of 115200. Press the ESP8266 EN/RST button, and it should print the ESP8266 IP address.
Demonstration
Open a browser on your local network and paste the ESP8266 IP address. You should get access to the web server page that displays the sensor readings.
The readings update automatically on the web page every 30 seconds.
You can have multiple clients on different web browser tabs or devices and it will update automatically on all clients.
Wrapping Up
In this tutorial, you’ve learned how to build a websocket server with the ESP8266 that serves a web page to display sensor readings. The sensor readings update automatically on the web page without the need to manually refresh it.
We hope you 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 ESP8266, we really recommend taking a look at our eBook:
Learn more about the ESP8266 with our resources:
- Home Automation using ESP8266
- Build Web Servers with ESP32 and ESP8266
- Firebase Web App with ESP32 and ESP8266
- Free ESP8266 Projects and Tutorials
Thank you for reading.
Hi Sara, I am a senior (>80+ y) and often visitor and often visiting your website ! I realized successfully many of your ESP8266 and ESP32 projects and just now I have been realizing the project you are describing in this article! Thank you very much for all the clear and precise indications for the quite complex ESP32 WebServer project with the BME280 sensor ! I am happy to have it solved with your help !
One thing: I am using mostly the ESP-WROOM-32P boards. At the beginning I had severe problems with the “Brownout” of the ESP32 development boards (30 pins), powered by the USB- terminals on my Desktop PC or my Laptop on with luck of enough of power ! Now I am using the ESP30 30P Expansion Board powered with a solid DC supply of 9 V/DC and it works fine! I recommend these Expansion Boards (exist only for ESP 32 30P) for less troubles with your Experiment proposals ! Have a good time, thanks once more for all your help on my DIY- activities!
That’s great!
Thanks for the recommendation. Can you share a link to the expansion board you’re talking about?
Regards,
Sara
Hi Sara, I just ordered four of the ESP32 Expansion Boards with Ali Express SAMIORE Store
ESP32 Entwicklung Bord
Expansion Board
CHF 0.96×5
AliExpress
Have a nice rest of the day, Bruno
Thanks for sharing.
Regards,
Sara
Hi Sara,
First of all I want to thank you very much for the tutorials that you make available here. Are amazing!! I’m a hobbyist so I have a lot of difficulties, since I don’t know programming in depth. Just a basic.
I’ve been trying to use this tutorial for a personal project but it seems like there’s an error in it.
At first I was only using the WebSocket functions from your tutorial in my sketch and it was giving me a memory allocation error. As my sketch is quite large, I spent several days trying to figure out what the problem was. Today, as I couldn’t find it, I decided to reproduce yours exactly as it is (the only difference is that I use a DS18B20 sensor). And the error also happened, which leads me to believe that there is something wrong with the code you provided.
The following happens:
I compile the sketch in the Arduino IDE and it loads to the ESP without problems. On the monitor, also all right. The SerialsPrints show that everything looks correct. But when I open the browser, almost immediately the problem happens. I’m going to paste here just a piece but it’s quite big. And almost immediately the esp8266 reboots. And again the problem happens. ESP just stops restarting when I close the browser.
The error is this:
Connecting to WiFi .......192.168.68.107
LittleFS mounted successfully
{"temperature":19.125}WebSocket client #1 connected from 192.168.68.109
User exception (panic/abort/assert)
--------------- CUT HERE FOR EXCEPTION DECODER ---------------
Panic core_esp8266_main.cpp:191 __yield
>>>stack>>>
ctx: sys
sp: 3fffed20 end: 3fffffb0 offset: 0010
3fffed30: 3fffed70 0000a245 3ffeef90 40212895
3fffed40: 000002ed 0000a245 3ffeef90 40210376
3fffed50: 0000000b 3ffeef90 3fffed8c 40206637
3fffed60: 3fff0fbc 00000020 3fff141c 40100bac
3fffed70: 0000000b 0000000b 3fff1d98 4020671c
3fffed80: 00001250 0000024a 3ffe8618 4010085e
3fffed90: 00001ae0 0000035c 3ffe8618 3fff1078
3fffeda0: 3fff1064 00000020 3fff1d98 40215684
3fffedb0: 3fffedc0 3fff1050 3fff100c 40211695
3fffedc0: 0000000b 3fff1d98 3fff18bc 00000004
3fffedd0: 3fff187c 3ffeefd8 3fff0fbc 3fff187c
3fffede0: 00000011 3fff0eb4 3fff1d92 40208a74
3fffedf0: 00001538 000002a7 3ffe8618 4010085e
3fffee00: 3fff1da3 0000003a 9be76c8b 00bb9e2c
MORE A LOT OF LINES........
3fffff90: 00000000 0016001f 40215644 3ffef2a0
3fffffa0: 3fffdad0 00000000 3ffef274 3ffef2a0
<<<stack<<<
--------------- CUT HERE FOR EXCEPTION DECODER ---------------
ets Jan 8 2013,rst cause:2, boot mode:(3,6)
load 0x4010f000, len 3424, room 16
tail 0
chksum 0x2e
load 0x3fff20b8, len 40, room 8
tail 0
chksum 0x2b
csum 0x2b
v000579c0
~ld
⸮œ⸮⸮N⸮s⸮⸮o|⸮d⸮l`#⸮⸮⸮⸮|s⸮l⸮o⸮⸮N⸮l`⸮œN⸮$⸮$⸮Connecting to WiFi .....
Thanks a lot if you can check what might be happening.
Hi.
do you get any errors on the web browser?
Open the Javascript console and check if you get any errors on the browser.
To open the Javascript console:
Windows/Linux: Press Control + Shift + J.
Mac: Press Command + Option + J.
Regards,
Sara
Hi Sara,
In the JS console, appears this:
Trying to open a WebSocket connection… script.js:16
Connection opened script.js:25
Failed to load resource: the server responded with
a status of 500 (Internal Server Error) /favicon.png:1
Connection closed script.js:30
Trying to open a WebSocket connection… script.js:16
Connection opened script.js:25
Connection closed script.js:30
How are you sending the readings to the web browser?
Regards,
Sara
The problem was reading the sensors. When I opened the browser and called the sensor reading, the problem happened. Even using the scripts you made available. I changed all the sending logic via WebSocket and managed to make it work. Thank you for your attention.
Hi Sara.
First I have to say that you are doing a great job for us that is not an Einstain.
I really like the LittleFS technology. It’s much more convenient to modify and test webfiles before they’re uploaded.
I tried to change in styles.css file but nothing happened. Then I discovered that there was a semicolon missing in the original file. In the class: card-title: color. After that changes was working.
Have a question also:
What are the class: “fas fa-thermometer-threequarters” in index.html doing?
Regards,
Ingvar Ask
Hi.
Yes. You are right.
There was a semicolon missing.
That shouldn’t be there. It’s from other project. It was basically to use icons from fontawesome: fontawesome.com/
Regards,
Sara