Movatterモバイル変換


[0]ホーム

URL:


Skip to content
HOMEESP32ESP8266ESP32-CAMRASPBERRY PIMICROPYTHONRPi PICOARDUINOREVIEWS

ESP8266 NodeMCU WebSocket Server: Control Outputs (Arduino IDE)

In this tutorial you’ll learn how to build a web server with the ESP8266 using WebSocket communication protocol. As an example, we’ll show you how to build a web page to control the ESP8266 outputs remotely. The output state is displayed on the web page and it updates automatically in all clients.

ESP8266 NodeMCU WebSocket Server Control Outputs Arduino IDE

The ESP8266 will be programmed using Arduino IDE and the ESPAsyncWebServer. We also have a similarWebSocket guide for the ESP32.

If you’ve been following some of ourprevious web server projects like this one, you may have noticed that if you have several tabs (in the same or on different devices) opened at the same time, the state doesn’t update in all tabs automatically unless you refresh the web page. To solve this issue, we can use WebSocket protocol – all clients can be notified when a change occurs and update the web page accordingly.

This tutorial was based on a project created and documented by one of our readers (Stéphane Calderoni). You can read his excellenttutorial here.

Introducing WebSocket

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. 

ESP32 ESP8266 WebSocket Server How it Works

The client establishes a WebSocket connection with the server through a process known asWebSocket 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.

Project Overview

Here’s the web page we’ll build for this project.

ESP32 WebSocket Server Toggle Outputs Project Overview
  • The ESP8266 web server displays a web page with a button to toggle the state of GPIO 2;
  • For simplicity, we’re controlling GPIO 2 – the on-board LED. You can use this example to control any other GPIO;
  • The interface shows the current GPIO state. Whenever a change occurs on the GPIO state, the interface is updated instantaneously;
  • The GPIO state is updated automatically in all clients. This means that if you have several web browser tabs opened on the same device or on different devices, they are all updated at the same time.

How it Works?

The following image describes what happens when click on the “Toggle” button.

ESP8266 NodeMCU WebSocket Web Server Update All Clients How it Works

Here’s what happens when you click on the “Toggle” button:

  1. Click on the “Toggle” button;
  2. The client (your browser) sends data via WebSocket protocol with the “toggle” message;
  3. The ESP8266 (server) receives this message, so it knows it should toggle the LED state. If the LED was previously off, turn it on;
  4. Then, it sends data with the new LED state to all clients also through WebSocket protocol;
  5. The clients receive the message and update the led state on the web page accordingly. This allows us to update all clients almost instantaneously when a change happens.

Preparing Arduino IDE

We’ll program the ESP8266 board using Arduino IDE, so make sure you have it installed in your Arduino IDE.

Installing Libraries – Async Web Server

We’ll build the web server using the following libraries:

You can install these libraries using the Arduino Library Manager. Go to Sketch Include Library > Manage Libraries and search for the libraries’ names.

Code for ESP8266 NodeMCU WebSocket Server

Copy the following code to your Arduino IDE.

/*********  Rui Santos & Sara Santos - Random Nerd Tutorials  Complete project details at https://RandomNerdTutorials.com/esp8266-nodemcu-websocket-server-arduino/  The above copyright notice and this permission notice shall be included in all  copies or substantial portions of the Software.*********/// Import required libraries#include <ESP8266WiFi.h>#include <ESPAsyncTCP.h>#include <ESPAsyncWebServer.h>// Replace with your network credentialsconst char* ssid = "REPLACE_WITH_YOUR_SSID";const char* password = "REPLACE_WITH_YOUR_PASSWORD";bool ledState = 0;const int ledPin = 2;// Create AsyncWebServer object on port 80AsyncWebServer server(80);AsyncWebSocket ws("/ws");const char index_html[] PROGMEM = R"rawliteral(<!DOCTYPE HTML><html><head>  <title>ESP Web Server</title>  <meta name="viewport" content="width=device-width, initial-scale=1">  <style>  html {    font-family: Arial, Helvetica, sans-serif;    text-align: center;  }  h1 {    font-size: 1.8rem;    color: white;  }  h2{    font-size: 1.5rem;    font-weight: bold;    color: #143642;  }  .topnav {    overflow: hidden;    background-color: #143642;  }  body {    margin: 0;  }  .content {    padding: 30px;    max-width: 600px;    margin: 0 auto;  }  .card {    background-color: #F8F7F9;;    box-shadow: 2px 2px 12px 1px rgba(140,140,140,.5);    padding-top:10px;    padding-bottom:20px;  }  .button {    padding: 15px 50px;    font-size: 24px;    text-align: center;    outline: none;    color: #fff;    background-color: #0f8b8d;    border: none;    border-radius: 5px;    -webkit-touch-callout: none;    -webkit-user-select: none;    -khtml-user-select: none;    -moz-user-select: none;    -ms-user-select: none;    user-select: none;    -webkit-tap-highlight-color: rgba(0,0,0,0);   }   /*.button:hover {background-color: #0f8b8d}*/   .button:active {     background-color: #0f8b8d;     box-shadow: 2 2px #CDCDCD;     transform: translateY(2px);   }   .state {     font-size: 1.5rem;     color:#8c8c8c;     font-weight: bold;   }  </style><title>ESP Web Server</title><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="data:,"></head><body>  <div class="topnav">    <h1>ESP WebSocket Server</h1>  </div>  <div class="content">    <div class="card">      <h2>Output - GPIO 2</h2>      <p class="state">state: <span id="state">%STATE%</span></p>      <p><button id="button" class="button">Toggle</button></p>    </div>  </div><script>  var gateway = `ws://${window.location.hostname}/ws`;  var websocket;  window.addEventListener('load', onLoad);  function initWebSocket() {    console.log('Trying to open a WebSocket connection...');    websocket = new WebSocket(gateway);    websocket.onopen    = onOpen;    websocket.onclose   = onClose;    websocket.onmessage = onMessage; // <-- add this line  }  function onOpen(event) {    console.log('Connection opened');  }  function onClose(event) {    console.log('Connection closed');    setTimeout(initWebSocket, 2000);  }  function onMessage(event) {    var state;    if (event.data == "1"){      state = "ON";    }    else{      state = "OFF";    }    document.getElementById('state').innerHTML = state;  }  function onLoad(event) {    initWebSocket();    initButton();  }  function initButton() {    document.getElementById('button').addEventListener('click', toggle);  }  function toggle(){    websocket.send('toggle');  }</script></body></html>)rawliteral";void notifyClients() {  ws.textAll(String(ledState));}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;    if (strcmp((char*)data, "toggle") == 0) {      ledState = !ledState;      notifyClients();    }  }}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);}String processor(const String& var){  Serial.println(var);  if(var == "STATE"){    if (ledState){      return "ON";    }    else{      return "OFF";    }  }  return String();}void setup(){  // Serial port for debugging purposes  Serial.begin(115200);  pinMode(ledPin, OUTPUT);  digitalWrite(ledPin, LOW);    // Connect to Wi-Fi  WiFi.begin(ssid, password);  while (WiFi.status() != WL_CONNECTED) {    delay(1000);    Serial.println("Connecting to WiFi..");  }  // Print ESP Local IP Address  Serial.println(WiFi.localIP());  initWebSocket();  // Route for root / web page  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){    request->send(200, "text/html", index_html, processor);  });  // Start server  server.begin();}void loop() {  ws.cleanupClients();  digitalWrite(ledPin, ledState);}

View raw code

Insert your network credentials in the following variables and the code will work straight away.

const char* ssid = "REPLACE_WITH_YOUR_SSID";const char* password = "REPLACE_WITH_YOUR_PASSWORD";

How the Code Works

Continue reading to learn how the code works or skip to theDemonstration section.

Importing Libraries

Import the necessary libraries to build the web server.

#include <ESP8266WiFi.h>#include <ESPAsyncTCP.h>#include <ESPAsyncWebServer.h>

Network Credentials

Insert your network credentials in the following variables:

const char* ssid = "REPLACE_WITH_YOUR_SSID";const char* password = "REPLACE_WITH_YOUR_PASSWORD";

GPIO Output

Create a variable calledledState to hold the GPIO state and a variable calledledPin that refers to the GPIO you want to control. In this case, we’ll control the on-board LED (that is connected toGPIO 2).

bool ledState = 0;const int ledPin = 2;

AsyncWebServer and AsyncWebSocket

Create anAsyncWebServer object on port 80.

AsyncWebServer server(80);

TheESPAsyncWebServer library includes a WebSocket plugin that makes it easy to handle WebSocket connections. Create anAsyncWebSocket object calledws to handle the connections on the/ws path.

AsyncWebSocket ws("/ws");

Building the Web Page

Theindex_html variable contains the HTML, CSS and JavaScript needed to build and style the web page and handle client-server interactions using WebSocket protocol.

Note: we’re placing everything needed to build the web page on theindex_html variable that we use on the Arduino sketch. Note that it may be more practical to have separated HTML, CSS and JavaScript files that then you upload to the ESP8266 filesystem and reference them on the code.

Recommended reading:ESP8266 Web Server using SPIFFS (SPI Flash File System)

Here’s the content of theindex_html variable:

<!DOCTYPE HTML><html><head>  <title>ESP Web Server</title>  <meta name="viewport" content="width=device-width, initial-scale=1">  <link rel="icon" href="data:,">  <style>  html {    font-family: Arial, Helvetica, sans-serif;    text-align: center;  }  h1 {    font-size: 1.8rem;    color: white;  }  h2{    font-size: 1.5rem;    font-weight: bold;    color: #143642;  }  .topnav {    overflow: hidden;    background-color: #143642;  }  body {    margin: 0;  }  .content {    padding: 30px;    max-width: 600px;    margin: 0 auto;  }  .card {    background-color: #F8F7F9;;    box-shadow: 2px 2px 12px 1px rgba(140,140,140,.5);    padding-top:10px;    padding-bottom:20px;  }  .button {    padding: 15px 50px;    font-size: 24px;    text-align: center;    outline: none;    color: #fff;    background-color: #0f8b8d;    border: none;    border-radius: 5px;    -webkit-touch-callout: none;    -webkit-user-select: none;    -khtml-user-select: none;    -moz-user-select: none;    -ms-user-select: none;    user-select: none;    -webkit-tap-highlight-color: rgba(0,0,0,0);   }   .button:active {     background-color: #0f8b8d;     box-shadow: 2 2px #CDCDCD;     transform: translateY(2px);   }   .state {     font-size: 1.5rem;     color:#8c8c8c;     font-weight: bold;   }  </style><title>ESP Web Server</title><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="data:,"></head><body>  <div>    <h1>ESP WebSocket Server</h1>  </div>  <div>    <div>      <h2>Output - GPIO 2</h2>      <p>state: <span>%STATE%</span></p>      <p><button>Toggle</button></p>    </div>  </div><script>  var gateway = `ws://${window.location.hostname}/ws`;  var websocket;  function initWebSocket() {    console.log('Trying to open a WebSocket connection...');    websocket = new WebSocket(gateway);    websocket.onopen    = onOpen;    websocket.onclose   = onClose;    websocket.onmessage = onMessage; // <-- add this line  }  function onOpen(event) {    console.log('Connection opened');  }  function onClose(event) {    console.log('Connection closed');    setTimeout(initWebSocket, 2000);  }  function onMessage(event) {    var state;    if (event.data == "1"){      state = "ON";    }    else{      state = "OFF";    }    document.getElementById('state').innerHTML = state;  }  window.addEventListener('load', onLoad);  function onLoad(event) {    initWebSocket();    initButton();  }  function initButton() {    document.getElementById('button').addEventListener('click', toggle);  }  function toggle(){    websocket.send('toggle');  }</script></body></html>

CSS

Between the<style></style> tags we include the styles to style the web page using CSS. 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 WebSocket tutorial.

<style>  html {    font-family: Arial, Helvetica, sans-serif;    text-align: center;  }  h1 {    font-size: 1.8rem;    color: white;  }  h2 {    font-size: 1.5rem;    font-weight: bold;    color: #143642;  }  .topnav {    overflow: hidden;    background-color: #143642;  }  body {    margin: 0;  }  .content {    padding: 30px;    max-width: 600px;    margin: 0 auto;  }  .card {    background-color: #F8F7F9;;    box-shadow: 2px 2px 12px 1px rgba(140,140,140,.5);    padding-top:10px;    padding-bottom:20px;  }  .button {    padding: 15px 50px;    font-size: 24px;    text-align: center;    outline: none;    color: #fff;    background-color: #0f8b8d;    border: none;    border-radius: 5px;    -webkit-touch-callout: none;    -webkit-user-select: none;    -khtml-user-select: none;    -moz-user-select: none;    -ms-user-select: none;    user-select: none;    -webkit-tap-highlight-color: rgba(0,0,0,0);   }   .button:active {     background-color: #0f8b8d;     box-shadow: 2 2px #CDCDCD;     transform: translateY(2px);   }   .state {     font-size: 1.5rem;     color:#8c8c8c;     font-weight: bold;   } </style>

HTML

Between the<body></body> tags we add the web page content that is visible to the user.

<div>  <h1>ESP WebSocket Server</h1></div><div>  <div>    <h2>Output - GPIO 2</h2>    <p>state: <span>%STATE%</span></p>    <p><button>Toggle</button></p>  </div></div>

There’s a heading 1 with the text “ESP WebSocket Server”. Feel free to modify that text.

<h1>ESP WebSocket Server</h1>

Then, there’s a heading 2 with the “Output – GPIO 2” text.

<h2>Output - GPIO 2</h2>

After that, we have a paragraph that displays the current GPIO state.

<p>state: <span>%STATE%</span></p>

The%STATE% is a placeholder for the GPIO state. It will be replaced with the current value by the ESP8266 at the time of sending the web page. The placeholders on the HTML text should go between% signs. This means that this%STATE% text is like a variable that will then be replaced with the actual value.

After sending the web page to the client, the state needs to change dynamically whenever there’s a change in the GPIO state. We’ll receive that information via WebSocket protocol. Then, JavaScript handles what to do with the information received to update the state accordingly. To be able to handle that text using JavaScript, the text must have an id that we can reference. In this case the id is state ( <span id=”state”>).

Finally, there’s a paragraph with the button to toggle the GPIO state.

<p><button>Toggle</button></p>

Note that we’ve given an id to the button (id=”button”).

JavaScript – Handling WebSockets

The JavaScript goes between the<script></script> tags. It is responsible for initializing a WebSocket connection with the server as soon the web interface is fully loaded in the browser and handling data exchange through WebSockets.

<script>  var gateway = `ws://${window.location.hostname}/ws`;  var websocket;  function initWebSocket() {    console.log('Trying to open a WebSocket connection...');    websocket = new WebSocket(gateway);    websocket.onopen    = onOpen;    websocket.onclose   = onClose;    websocket.onmessage = onMessage; // <-- add this line  }  function onOpen(event) {    console.log('Connection opened');  }  function onClose(event) {    console.log('Connection closed');    setTimeout(initWebSocket, 2000);  }  function onMessage(event) {    var state;    if (event.data == "1"){      state = "ON";    }    else{      state = "OFF";    }    document.getElementById('state').innerHTML = state;  }  window.addEventListener('load', onLoad);  function onLoad(event) {    initWebSocket();    initButton();  }  function initButton() {    document.getElementById('button').addEventListener('click', toggle);  }  function toggle(){    websocket.send('toggle');  }</script>

Let’s take a look at how this works.

The gateway is the entry point to the WebSocket interface.

var gateway = `ws://${window.location.hostname}/ws`;

window.location.hostname gets the current page address (the web server IP address).

Create a new global variable calledwebsocket.

var websocket;

Add an event listener that will call theonload function when the web page loads.

window.addEventListener('load', onload);

Theonload() function calls theinitWebSocket() function to initialize a WebSocket connection with the server and theinitButton() function to add event listeners to the buttons.

function onload(event) {  initWebSocket();  initButton();}

TheinitWebSocket() 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;}

When the connection is opened, we simply print a message in the console and send a message saying “hi”. The ESP8266 receives that message, so we know that the connection was initialized.

function onOpen(event) {  console.log('Connection opened');  websocket.send('hi');}

If for some reason the web socket connection is closed, we call theinitWebSocket() function again after 2000 milliseconds (2 seconds).

function onClose(event) {  console.log('Connection closed');  setTimeout(initWebSocket, 2000);}

ThesetTimeout() method calls a function or evaluates an expression after a specified number of milliseconds.

Finally, we need to handle what happens  when we receive a new message. The server (your ESP board) will either send a “1” or a “0” message. Accordingly to the received message, we want to display an “ON” or a “OFF” message on the paragraph that displays the state. Remember that<span> tag withid=”state”? We’ll get that element and set its value to ON or OFF.

function onMessage(event) {  var state;  if (event.data == "1"){    state = "ON";  }  else{    state = "OFF";  }  document.getElementById('state').innerHTML = state;}

TheinitButton() function gets the button by its id (button) and adds an event listener of type‘click’.

function initButton() {  document.getElementById('button').addEventListener('click', toggle);}

This means that when you click the button, thetoggle function is called.

Thetoggle function sends a message using the WebSocket connection with the‘toggle’ text.

function toggle(){  websocket.send('toggle');}

Then, the ESP8266 should handle what happens when it receives this message – toggle the current GPIO state.

Handling WebSockets – Server

Previously, you’ve seen how to handle the WebSocket connection on the client side (browser). Now, let’s take a look on how to handle it on the server side.

Notify All Clients

ThenotifyClients() function notifies all clients with a message containing whatever you pass as a argument. In this case, we’ll want to notify all clients of the current LED state whenever there’s a change.

void notifyClients() {  ws.textAll(String(ledState));}

TheAsyncWebSocket class provides atextAll() method for sending the same message to all clients that are connected to the server at the same time.

Handle WebSocket Messages

ThehandleWebSocketMessage() function is a callback function that will run whenever we receive new data from the clients via WebSocket protocol.

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;    if (strcmp((char*)data, "toggle") == 0) {      ledState = !ledState;      notifyClients();    }  }}

If we receive the “toggle” message, we toggle the value of theledState variable. Additionally, we notify all clients by calling thenotifyClients() function. This way, all clients are notified of the change and update the interface accordingly.

if (strcmp((char*)data, "toggle") == 0) {  ledState = !ledState;  notifyClients();}

Configure the WebSocket server

Now we need to configure an event listener to handle the different asynchronous steps of the WebSocket protocol. This event handler can be implemented by defining theonEvent() as follows:

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;  }}

Thetype argument represents the event that occurs. It can take the following values:

  • WS_EVT_CONNECT when a client has logged in;
  • WS_EVT_DISCONNECT when a client has logged out;
  • WS_EVT_DATA when a data packet is received from the client;
  • WS_EVT_PONG in response to a ping request;
  • WS_EVT_ERROR when an error is received from the client.

Initialize WebSocket

Finally, theinitWebSocket() function initializes the WebSocket protocol.

void initWebSocket() {  ws.onEvent(onEvent);  server.addHandler(&ws);}

processor()

Theprocessor() function is responsible for searching for placeholders on the HTML text and replace them with whatever we want before sending the web page to the browser. In our case, we’ll replace the%STATE% placeholder withON if theledState is1. Otherwise, replace it withOFF.

String processor(const String& var){  Serial.println(var);  if(var == "STATE"){    if (ledState){      return "ON";    }    else{      return "OFF";    }  }}

setup()

In thesetup(), initialize the Serial Monitor for debugging purposes.

Serial.begin(115200);

Set up theledPin as anOUTPUT and set it toLOW when the program first starts.

pinMode(ledPin, OUTPUT);digitalWrite(ledPin, LOW);

Initialize Wi-Fi and print the ESP8266 IP address on the Serial Monitor.

WiFi.begin(ssid, password);while (WiFi.status() != WL_CONNECTED) {  delay(1000);  Serial.println("Connecting to WiFi..");}// Print ESP Local IP AddressSerial.println(WiFi.localIP());

Initialize WebSocket protocol by calling theinitWebSocket() function created previously.

initWebSocket();

Handle Requests

Serve the text saved on theindex_html variable when you receive a request on the root/ URL – you need to pass theprocessor function as an argument to replace the placeholders with the current GPIO state.

server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){  request->send_P(200, "text/html", index_html, processor);});

Finally, start the server.

server.begin();

loop()

The LED will be physically controlled on theloop().

void loop() {  ws.cleanupClients();  digitalWrite(ledPin, ledState);}

Note that we all call thecleanupClients() method. Here’s why (explanation from the ESPAsyncWebServer library GitHub page):

Browsers sometimes do not correctly close the WebSocket connection, even when theclose() function is called in JavaScript. This will eventually exhaust the web server’s resources and will cause the server to crash. Periodically calling thecleanupClients() function from the mainloop()limits the number of clients by closing the oldest client when the maximum number of clients has been exceeded. This can be called every cycle, however, if you wish to use less power, then calling as infrequently as once per second is sufficient.

Demonstration

After inserting your network credentials on thessid andpassword variables, you can upload the code to your board. Don’t forget to check if you have the right board and COM port selected.

After uploading the code, open the Serial Monitor at a baud rate of 115200 and press the on-board EN/RST button. The ESP IP address should be printed.

Open a browser on your local network and insert the ESP8266 IP address. You should get access to the web page to control the output.

ESP32 WebSocket Server Toggle Outputs Project Overview

Click on the button to toggle the LED. You can open several web browser tabs at the same time or access the web server from different devices and the LED state will be update automatically in all clients whenever there’s a change.


Wrapping Up

In this tutorial you’ve learned how to set up a WebSocket server with the ESP8266. The WebSocket protocol allows a full duplex communication between the client and the server. After initializing, the server and the client can exchange data at any given time.

This is very useful because the server can send data to the client whenever something happens. For example, you can add aphysical button to this setup that when pressed notifies all clients to update the web interface.

In this example, we’ve shown you how to control one GPIO of the ESP8266. You can use this method to control more GPIOs. You can also use the WebSocket protocol to send sensor readings or notifications at any given time.

We hope you’ve found this tutorial useful. We intend to create more tutorials and examples using the WebSocket protocol. So, stay tuned.

Learn more about the ESP8266 with our resources:



SMART HOME with Raspberry Pi ESP32 and ESP8266 Node-RED InfluxDB eBook
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »

Recommended Resources

Build a Home Automation System from Scratch » With Raspberry Pi, ESP8266, Arduino, and Node-RED.

Home Automation using ESP8266 eBook and video course » Build IoT and home automation projects.

Arduino Step-by-Step Projects »Build 25 Arduino projects with our course, even with no prior experience!

What to Read Next…


Enjoyed this project? Stay updated by subscribing our newsletter!

74 thoughts on “ESP8266 NodeMCU WebSocket Server: Control Outputs (Arduino IDE)”

  1. Hi,
    very interesting, you say that we can sens also a sensor reading.
    But how to do this.

    Thanks
    Renzo Giurini

    Reply
  2. Sorry, in the second line “send” instead of “sens”
    Renzo Giurini

    Reply
  3. Hi Rui and Sara, Another well presented tutorial where I have again expanded my knowledge, especially in the web server setup side of things and now sockets, thank you. But like the other ESP server tutorials I’m finding it too hard to expand the sketch to more than one button. In one of your first ESP8266 server tutorials you had two buttons, that was great as it allowed someone to see what portions of the code needed to be duplicated/expanded out and what parts were common. Also I noticed that source project idea mentioned at the top of this page, in VSCode, had a physical button as well but you have not included this here. It would be great to see your next tutorial in this theme with more than one input and output. Many thanks.

    Reply
  4. Excellent work

    I could not find any trace of referance to The AsyncWebSocket class method textAll()

    thanks

    Reply
  5. Hello,
    When I compiling the sketch, I get the following message:
    “class AsyncWebSocket’ has no member named ‘cleanupClients'”
    In line: “ws.cleanupClients();”

    Kind Regards
    Juergen B.

    Reply
  6. Good Afternoon,
    how do I have to extend the JavaScript functions to display the values from a sensor (e.g. DHT11)?
    websocket.onmessage = onTemperature; ?
    etc.
    Kind Regards
    Juergen B.

    Reply
    • Hi.
      You can do that on the onMessage function.
      For example, you need to have a paragraph to display the reading with a specific id (for example “reading”).
      Then, the onMessage function would be something like this:

      function onMessage(event) {
      var reading = event.data;
      document.getElementById(“reading”).innerHTML=reading;
      }

      Regards,
      Sara

      Reply
      • Good Afternoon,
        Many thanks for the answer.
        But how is the sensor value passed to event.data?
        In the existing sketch, the value ‘0/1’ is passed to event.data.
        Kind regards
        Juergen B.

        Reply
        • Hello,
          with: void notifyTemperature () {
          ws.textAll (String (t));
          }
          can I send the temperature value to event.data.
          As a test, I entered the “notifyTemperature ()” function in the “handleWebSocketMessage” function.
          The “handleWebSocketMessage” function is only executed when I press the toggle button (WS_EVT_DATA = 1).
          Which WS_? would I have to use?
          Kind regards
          Juergen

          Reply
          • Hi.
            Yes, with
            with:
            void notifyTemperature () {
            ws.textAll (String (t));
            }
            You can send the temperature to the client.

            The handleWebSocketMessage() is a callback function that is called when the server receives a message, which is not the case. You want to send data to the client.

            So, use ws.textAll().

            Regards,
            Sara

  7. Hello,
    but how can I call the “notifyTemperature ()” function so that the sensor value is continuously displayed?

    Kind Regards

    Juergen B.

    Reply
  8. Hello,
    my next step is to display two sensor values (temperature, humidity).
    Since the two sensor values have the same value range (T = 25 ° C, H = 25%), “Temperature = 25” and Humidity = 25 “should be sent as the event.
    These events must then be separated in the “onMessage (event)” function.

    Kind Regards

    Juergen B.

    Reply
    • Hello,
      with the Javascript command “split ()” I separated the sensor string and was able to display the two sensor values separately.
      Thank you very much for the tutorial, so I learned something about “WebSocket” and “Javascript” again.

      Kind Regards
      Juergen B.

      Reply
  9. when I refresh the web page , the digital output to the pin goes LOW.

    I think this is due to the fact that the websocket gets initialized every time the window loads.

    or Am i missing something

    Reply
  10. I would like to apologize regarding my previous post (not published yet)

    I found the issue

    I made modification to the code that caused the output to go off when refreshing the browser

    so please discard this post and the previous one

    Many thanks and sorry for time wasted

    Philip

    Reply
  11. Can I see an example of an OTA update via WebSocket? Thanks.

    Reply
  12. Hey Rui and Sara, these tutorials are extremely helpful, so thank you very much for providing them.

    I do have one question regarding this tutorial and the ability to expand to monitor more than one output. First off is it possible using the websocket protocol? Also, can it be done by just adding additional HTML sections to show that extra GPIO output to be monitored?

    Thanks again.

    Reply
    • Hi.
      Yes, you can use websockets to control multiple outputs.
      At the moment, we don’t have that tutorial. But we intend to publish something like that soon.
      Regards,
      Sara

      Reply
      • Hey Sara, thanks for the reply.
        Thanks again for the tutorial, it helped me learn so much about these useful microcontrollers. I’ll be watching for that tutorial when it gets published, thanks!

        Reply
  13. Hi!
    Wondering what the code looks like for another ESP8266 to act as an async WS Client to your async WS server?
    Any examples that you care to share?

    Thanks

    Reply
  14. Hello,

    thank you for this exelent tutorial and detailed descritpion for the websocket dataexchange. I used your code and add more button and slider for the LED control.
    I send the states and values from the EPS to the clients as JSON over websocket.

    Bye
    Karatzie

    Reply
    • Hey Karatzie,

      Could you share the code that you worked on to add more buttons and sliders? I added more buttons on the page itself(pretty simple, just formatting) but I cant seem to display the correct state of an output that is connected to that second button (on or off).

      Thanks,
      Arthur

      Reply
  15. Hi everyone, I’m not a newbie, but I just can’t get how to modify the code for multiple gpios… someone kindly guide in the right direction…. be it code or psuedo-code I don’t mind

    Reply
    • You need to add a target to the html send. Simply format the control message as: target/command, like GPIO7/ON and GPIO7/OFF. Example code: websocket.send(‘GPIO7/ON’);

      On the ESP, parse the message into two parts, target and command:

      [code]
      void handleWebSocketMessage(voidarg, 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;
      Serial.printf(“>> %s\n”, data);

      // Parse data into parts and process as needed.
      String msg = (char*)data;
      int pos = msg.indexOf('/');
      String gpio;
      String cmd;
      if (pos != -1) {
      // Formatted as expected
      gpio = msg.substring(0, pos);
      cmd = msg.substring(pos+1);
      } else {
      // Set a default target.
      gpio = "esp147";
      cmd = msg;
      }
      Serial.printf("Parsed as target: %s and cmd: %s\n", gpio.c_str(), cmd.c_str());

      //...add what to do here.

      //-- original example -------------
      if (cmd.equals("toggle")) {
      ledState = !ledState;
      notifyClients();
      return;
      }
      //---------------------------------

      // If not processes, send an error message to the Serial monitor.
      Serial.println("Error: unknown message received.");

      }
      }

      [/code]

      Reply
      • Thanks a lot Greg! I used:…
        function initWebsocket(){
        …..onMessage1;
        ….. onMessage2;
        ….
        function initButton(){
        Document.getE…(‘button1’)….(, toggle1)

        Document.getE…(‘button2’)….(, toggle2)
        }…..
        function toggle1(){
        Websocket.send(‘toggle1’);
        }
        function toggle2(){
        Websocket.send(‘toggle2’);
        }….
        void handleW..
        ….if(strcmp((chardata,”toggle1″…if(strcmp((chardata,”toggle2″…
        All these parts seem to behave as expected except for

        function onMessage1(event){
        if (event.data == “1”){
        document.get….’state1′.innerH

        function onMessage2 (event){
        if (event.data == “1”){
        document.get….’state2′.innerHT….because as in the original code, only the last button’s ‘state’ automatically updates while all other require a reload…
        How can I resolve this…

        Reply
  16. Thanks a lot Sara for Great example.
    Thanks too Greg!
    In my modifications I used:…
    function initWebsocket(){
    …..onMessage1;
    ….. onMessage2;
    ….
    function initButton(){
    Doc….Id(‘button1’)….(.., toggle1)
    Doc….Id(‘button2’)….(.., toggle2)
    }…..
    function toggle1(){
    Websocket.send(‘toggle1’);
    }
    function toggle2(){
    Websocket.send(‘toggle2’);
    }….
    void handleW..
    ….if(strcmp((chardata,”toggle1″…if(strcmp((chardata,”toggle2″…
    All these parts seem to behave as expected except for

    function onMessage1(event){
    if (event.data == “1”){
    document.get….’state1′.innerH

    function onMessage2 (event){
    if (event.data == “1”){
    document.get….’state2′.innerHT….because as in the original code, only the last button’s ‘state’ automatically updates while all other require a reload…
    How can I resolve this…

    Reply
  17. Pretty much the same way. From the ESP to the webpage, send formatted messages like, buttoName/buttonState. Example:
    btton_01/on
    and process them in the webpage’s js method “onMessage()”.

    Hope it helps.

    greg

    Reply
  18. Pardon my ignorance everyone..web design, js and websockets is all new to me…

    Thanks again Greg
    To my surprise the solution was as simple as asking myself where “1” was coming from in the function …onMessage…event.data

    Reply
  19. The “event.data” is anything you want to pass via the websocket send methods. I simply suggest that instead of 0 or 1, you pass a formatted message like:
    webpage to ESP: gpioXX/value, and likewise for
    ESP to webpage: buttonName/state where state is 0 or 1.

    Since the original example only uses one button, so its name is not necessary to pass and a simply on/off (0/1) value is sufficient for the message. You need more.

    Greg

    Reply
    • Sorry, but I’m trying to replicate this function with two or more buttons and I just can’t find where this value “0” or “1” is being passed from, either on the webpage to ESP part or vice versa,

      Reply
  20. Added a second button. I edited the code, it works, but i have some problem.
    The buttons function correctly, and so do the LEDs. BUT! The status is displayed
    simultaneously on two buttons. As if they are parallel. For example: you turn on the first LED, the status shows that two LEDs have turned on, although in fact, as expected
    , only one has turned on. I can’t find solving the problem. Help me please.

    html code:
    [code]

    Output – GPIO 32

    Status: %STATE1%

    Switcher-1

    Output – GPIO 33

    Status: %STATE2%

    Switcher-2

    [/code]

    java scrypt:
    [code]
    var gateway =ws://${window.location.hostname}/ws;
    var websocket;
    window.addEventListener(‘load’, onLoad);
    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’);
    }

    function onClose(event) {
    console.log(‘Connection closed’);
    setTimeout(initWebSocket, 2000);
    }

    function onMessage(event) {
    var state1;
    if (event.data == “1”){
    state1 = “ON”;
    }
    else{
    state1 = “OFF”;
    }
    document.getElementById(‘state1’).innerHTML = state1;

    var state2;
    if (event.data == "1"){
    state2 = "ON";
    }

    else{
    state2 = “OFF”;
    }
    document.getElementById(‘state2’).innerHTML = state2;
    }

    function onLoad(event) {
    initWebSocket();
    initButton();
    }

    function initButton() {
    document.getElementById(‘button1’).addEventListener(‘click’, toggle1);
    document.getElementById(‘button2’).addEventListener(‘click’, toggle2);
    }

    function toggle1(){
    websocket.send(‘toggle1’);
    }

    function toggle2(){
    websocket.send(‘toggle2’);
    }
    [/code]

    ESP8266 code:
    [code]
    void notifyClients1() {
    ws.textAll(String(ledState1));
    }

    void notifyClients2() {
    ws.textAll(String(ledState2+2));
    }

    void handleWebSocketMessage(voidarg, 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;
    Serial.printf(“>> %s\n”, data);
    if (strcmp((char)data, “toggle1”) == 0) {
    ledState1 = !ledState1;
    notifyClients1();
    }
    if (strcmp((char
    )data, “toggle2”) == 0) {
    ledState2 = !ledState2;
    notifyClients2();
    }
    }
    }
    [/code]

    Reply
  21. Sara Santos,

    Thank you for your comment, and I apologize in the same line.

    I apologize for I had no intent on disrupting you tutorial thread. One of your commenters needed help in extending your example. I took it off line so as not to abuse the thread. I extended the example for him/her and put my results onto GitHub for transfer/downloading. Another commenter emailed me with a similar request, so I posted the GitHub link.

    I am sorry this disruption of your tutorial thread. It was not my intent.

    BTW Sara. I also integrate Alexa for up to 99 custom voice commands. Push buttons on a web-page or ask Alexa to do it for you: “Alexa, set Netflix to HBO” for example. And all ESP GPIO pins accessible with 100 settings available for each. It also enables ESP direct commands like “info”, “reboot”, …for commands unrelated to a GPIO pin.

    It includes a simple online “monitor” and OTA capabilities. If not a stand-alone ESP installation, I implement a “WebSocket Net” with a router-esp and many other worker-esp nodes. The node code easily fits/runs on the Sonoff basic switch as well, my preferred alternative to the traditional “GPIO pin to relay” switch.

    Anyway, a great tutorial!

    TKS,
    Greg

    Reply
  22. Another solution. Added two buttons. I tried to minimally change the original example. Implemented on SPIFFS. Links to the original lesson are saved.
    Many thanks to Greg Baker for his help and detailed lessons!
    You can download the code herehttps://github.com/humaxoid/Websocket_buttons
    Any remark are welcome.

    Reply
    • Hola
      Me encantó este tutorial no paró de estudiarlo
      Este código funciona con una red local pero yo quisiera controlar desde fuera de mi casa
      Alguien me puede ayudar con eso

      Reply
    • 121 / 5000
      Kết quả dịch
      I’m new to websocket
      Can you explain more about your code?
      I also don’t understand JSON very well

      Reply
  23. Thanks for all your good work and knowledge sharing! just I¡d like to point out that function processor gives an error because doesn’t always return a value. I’m trying to figure out the return value.

    Reply
  24. I wanted to change the default port “AsyncWebServer server(80)” to another port number, for example, AsyncWebServer server(5055). When I did this I was able to open the webpage via 10.0.0.26:5055, however the button did not function. When I click on the Toggle button nothing happens.
    There is no other processes on my network using port 5055.
    Any ideas why?

    Reply
    • I have the same issue with port forwarding. Did you find any solution?

      Reply
      • Okay, I got it.
        If you change the port of the web server you have to add it to the JS as well.
        Like;
        AsyncWebServer server(250);
        var gateway =ws://${window.location.hostname}:250/ws;

        For those who struggle with port-forwarding, my Asus router was letting me choose TCP, UDP, Both, Other, but none of the options else than “other” were not passing WS packets. In addition, if I chose “other” the router does not let me to chose a port higher than 255.
        Hope it helps someone.

        Reply
  25. Hi, thanks for sharing this excellent tutorial. I want to make my project with websocket and mqtt,
    I know it is possible, but I have no idea what to do. Can you give me some suggestions?

    Reply
  26. How to identify data from different pages? All my pages are hosted in spiffs

    Reply
  27. The application runs fine on both client and server sides, sending and receiving data. However, if the server side disconnects (power cycle or upload new code), the client (Chrome) won’t reconnect to the websocket. I can reload/refresh the web page, and it claims (according to the console log) to be connecting to the websocket, but it does not. The only solution I have found that works is to close the tab, and then restart a new session.
    Any ideas on this?

    Reply
  28. hello, can someone help me out..

    when I press the toggle button the status in the website does not change and the led does not turn on. I have no idea where to look for the problem…

    thanks in advance lars

    Reply
    • Hi.
      Did you upload all the required files to the ESP8266?
      Do you get any error messages?
      Open the web browser javascript console and check if it prints any error messages when you toggle the buttons.
      Regards,
      Sara

      Reply
  29. Lads, your code that is being passed around from post to post is unsafe and is actually a bad idea:
    AwsFrameInfo *info = (AwsFrameInfo)arg;
    if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT) {
    data[len] = 0;

    Here len specifies the exact amount of bytes pointed to by *data (as is mandated by WebSocket RFC) – check library code and examples of how to treat data.
    Setting data[len] to 0 is basically writing to the memory that might be allocated for something else – len index points beyond the array boundary.

    Reply
  30. Hello , is there a away to access my esp from web without port forword in my router?????

    Reply
  31. Good evening, I hope you are well, first of all thank you for this very interesting tutorial, my concern is this

    how to always have a single button when you press the LED lights up when you let go the LED goes off?

    thank you and good evening

    Reply
  32. Hi.
    Thank you very much for your answer, I am satisfied

    Reply
  33. Hi.
    I think you are fine, I come back again, I wanted to know if there is a way to make two esp32 cards communicate by Websocket? I really like this protocol.
    thank you
    Jonas Mokili

    Reply
  34. Hi and thanks for this great tutorial! Do you have a suggestion on what to modify in the code so that pressing the button turns the LED on for 10 seconds and then it turns off automatically (without a need to press the toggle button)? I tried now for some time with a for loop in the loop section or modifying the handleWebSocketMessage function but all that results in wrong behavior. Could you please point me in the right direction? Thanks!

    Reply
  35. hey… the code works great and all,
    but then I tried using this with a react(next) app I made by my self

    everytime I try to connect to the ws endpoint, it fails

    Reply
  36. Good evening, I have been trying to find a solution to my problem for days. I’m using your sketch, but I can not get me back the status of the LED if I refresh the page, the problem does not exist if instead I click on the toggle button, which after being pressed returns the status and updates from on to off and vice versa, I specify that the server is not on arduino but I loaded the index page on a remote server. Thank you for any reply.

    Reply
    • Hi.
      Can you open the javascript console on your web browser, refresh the web page and check which messages do you get?
      Regards,
      Sara

      Reply
      • Thanks for the reply, opening the console I do not receive any message outside of connection attempt and open connection. In the IDE console I only get connected by ID and IP when I log in from outside, while locally I also get the STATE. I insert the link of the remote server where the index page is running in case it can be useful. Thank you.http://185.182.186.170/arduino/

        Reply
      • Sorry if I insist, have you had the opportunity to verify the behavior of the page? Last thing, would you help me with a change, I should add another button, but I have to make sure that only one button at a time is ON, example: the first is on, the second is off, if the second is on the first goes off. I hope I have been able to explain what I should do and receive a kind answer to my problems. Thank you in advance.

        Reply
  37. hello…thank you very much for the tutorial that I really need. can you help how to change the toggle button to a temporary button (the button is active as long as I press the mouse) thanks for the help

    Reply
  38. I am trying to use AutoconnectAP with this code but there are conflicts in these two libraries. Is there any example where this two libraries are used together?

    Reply
  39. initWebSocket();
    // Route for root / web page
    server.on(“/”, HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(200, “text/html”, index_html, processor);

    above fct may typo error —-> i.e. missing _P
    request->send_P(200, “text/html”, index_html, processor);

    Reply
  40. Greetings:
    I haven’t been able to get this program to run.
    Everything is OK until I enter the address in my browser then it
    errors with this error:
    ————— 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
    v0004d170
    ~ld

    Connecting to WiFi..
    192.168.1.16

    I tried with windows 11 IDE2.3.6 and windows 10 IDE1.8.19 all
    with the same results.
    I ran the ESP32 version and it works OK.
    The two programs are the same except for the libraries.
    I am using the Libraries recommended.
    ESP AsyncTCP by ESP32Async version 2.0.0
    ESP Async WebServer by ESP32Async version 3.8.0
    Both say they are for ESP8266 and ESP32
    Any help is appreciated.
    Bob

    Reply

Leave a CommentCancel reply

Learn ESP8266

ESP8266 Introduction

ESP8266 Arduino IDE

ESP8266 Arduino IDE 2.0

VS Code and PlatformIO

ESP8266 Pinout

ESP8266 Inputs Outputs

ESP8266 PWM

ESP8266 Analog Inputs

ESP8266 Interrupts Timers

ESP8266 Deep Sleep

Protocols

ESP8266 Web Server

ESP8266 MQTT

ESP8266 ESP-NOW

ESP8266 Wi-Fi

ESP8266 WebSocket

ESP8266 ESP-MESH

ESP8266 Email

ESP8266 HTTP GET POST

HTTP GET Web APIs

HTTP POST Web APIs

ESP-NOW One-to-Many

ESP-NOW Many-to-One

ESP-NOW Two-Way

ESP-NOW ESP8266 + ESP32

ESP-NOW + Wi-Fi Web Server

Server-Sent Events

Web Servers

Output Web Server

PWM Slider Web Server

PWM Multiple Sliders Web Server

Async Web Server

Relay Web Server

DHT Web Server

BME280 Web Server

BME680 Web Server

DS18B20 Web Server

Plot/Chart Web Server

Chart Multiple Series Web Server

SPIFFS Web Server

Thermostat Web Server

Input Fields Web Server

Images Web Server

RGB LED Web Server

Momentary Switch Web Server

Physical Button Web Server

Timer/Pulse Web Server

Gauges Web Server

HTTP Auth Web Server

ESP8266 WiFiManager

Stepper Motor WebSocket

DIY Cloud

ESP8266 Weather Station

Control GPIOs

View Sensor Readings

ESP8266 MySQL

ESP8266 PHP Email

Cloud Node-RED Dashboard

Cloud MQTT Broker

Firebase

Firebase Realtime Database

Firebase Web App

Firebase Authentication

Firebase BME280

Firebase Web App Sensor Readings

Modules and Sensors

ESP8266 Relay Module

ESP8266 PIR

ESP8266 HC-SR04

ESP8266 AC PIR

ESP8266 Reed Switch

ESP8266 DHT11/DHT22

ESP8266 BME280

ESP8266 BME680

ESP8266 DS18B20

ESP8266 BMP388

ESP8266 Mains Voltage

ESP8266 Stepper Motor

ESP8266 I2C Multiplexer

Displays

ESP8266 OLED

ESP8266 LCD

ESP8266 Nextion

OLED Temperature

MQTT

ESP8266 MQTT

MQTT Output RPi

MQTT DHT RPi

MQTT SQLite RPi

MQTT DHT11/DHT22

MQTT BME280

MQTT BME680

MQTT DS18B20

ESP8266 MPU-6050

Other Projects

ESP8266 Alexa

ESP8266 Google Sheets

Multisensor Shield

Multisensor Shield Node-RED

ESP8266 Daily Task

ESP8266 Wi-Fi Button

Latching Power Circuit

Telegram Control Outputs

Telegram Sensor Readings

Telegram Detect Motion

Telegram Group

Telegram Door Monitor

ESP8266 WebSerial

Useful Guides

ESP8266 Troubleshooting

ESP8266 Access Point

ESP8266 Fixed IP Address

ESP8266 MAC Address

ESP8266 Reconnect Wi-Fi

ESP8266 Hostname

ESP8266 OTA

ESP8266 OTA Arduino

ESP8266 OTA VS Code

ESP8266 Solar Panels

ESP8266 Voltage Regulator

ESP8266 ThingSpeak

ESP8266 Install SPIFFS

ESP8266 Install LittleFS

ESP8266 Time and Date

ESP8266 Epoch Time

ESP8266 JSON

VS Code and PlatformIO

VS Code LittleFS

VS Code Workspaces

Learn More

Learn ESP32

Learn ESP8266

Learn ESP32-CAM

Learn MicroPython

Learn Arduino

Build Web Servers eBook

ESP8266 eBook »

Affiliate Disclosure:Random Nerd Tutorials is a participant in affiliate advertising programs designed to provide a means for us to earn fees by linking to Amazon, eBay, AliExpress, and other sites. We might be compensated for referring traffic and business to these companies.



Learn ESP32 with Arduino IDE eBook » Complete guide to program the ESP32 with Arduino IDE!



SMART HOME with Raspberry Pi, ESP32, and ESP8266 » learn how to build a complete home automation system.



Learn Raspberry Pi Pico/Pico W with MicroPython​ » The complete getting started guide to get the most out of the the Raspberry Pi Pico/Pico W (RP2040) microcontroller board using MicroPython programming language.



🔥 Learn LVGL: Build GUIs for ESP32 Projects​ » Learn how to build Graphical User Interfaces (GUIs) for ESP32 Projects using LVGL (Light Versatile Graphics Library) with the Arduino IDE.

Download Our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.


[8]ページ先頭

©2009-2025 Movatter.jp