ESP32 UNO - WebSocket

Want your browser to talk to the ESP32 Uno without ever pressing reload? A WebSocket server on the ESP32 Uno form board keeps one live link open, so messages fly both ways in real time. Here you build a small chat page: type text in the browser, and the board answers at once.

By the end, you can:

  1. Explain what a WebSocket is and why it beats page reloads
  2. Run a web server and a WebSocket server on the board with Arduino code
  3. Load the chat page from a separate index.h file
  4. Send a message from your phone or PC and read the reply
ESP32 Uno websocket

Components You Need

1×ESP32 Uno-form Board
1×USB Cable Type-A to Type-C (for USB-A PC)
1×USB Cable Type-C to Type-C (for USB-C PC)

Or you can buy the following kits:

1×DIYables Sensor Kit (18 sensors/displays)
Disclosure: Some of the links provided in this section are Amazon affiliate links. We may receive a commission for any purchases made through these links at no additional cost to you.
Additionally, some of these links are for products from our own brand, DIYables .

Good to know: This project uses only the built-in WiFi of the ESP32 Uno. You do not connect any wire or module.

What Is a WebSocket on the ESP32 Uno?

Goal: understand the one idea behind this whole tutorial.

A WebSocket is a permanent, two-way channel between a web browser and a server. Normal web pages work like postcards: you ask, the server answers, and the link closes. A WebSocket works like a phone call: both sides stay on the line and can speak at any time.

Way to talk Normal web page WebSocket
Connection Closed after each answer Stays open
Who can start a message Only the browser Browser or board
Need to reload Yes No

Online games, live chat and stock price boards all use this trick.

Why Use WebSocket to Control the ESP32 Uno?

Goal: see why a live link makes control feel instant.

Picture a toy car that you drive from your phone. With plain web pages, each turn or speed change means a page reload. That is slow and clumsy. With a WebSocket, your phone and the ESP32 Uno keep a direct line, so the car reacts the moment you press a button.

In short, a WebSocket lets you:

  • Send data from the browser to the ESP32 Uno with no reload
  • Push data from the ESP32 Uno to the browser with no reload

What You Gain

Benefit What It Means for You
Real-time control Commands reach the board almost at once
Persistent link No refresh needed while the page is open
Low overhead Only tiny messages travel, not a full page

ESP32 Uno Pinout

Every Uno header pin on the ESP32 Uno form board has a GPIO number, and code uses that number. This project needs no wires, but keep the diagram handy for when you add LEDs, relays or sensors to control over WebSocket.

ESP32 Uno pinout diagram

Build the Web Chat

Goal: run a chat server on the board and open its page in your browser.

The page (HTML, CSS and JavaScript) lives in its own file, index.h. So the Arduino IDE sketch has two files:

File Role
newbiely.com.ino Main code, starts the web server and the WebSocket server
index.h The chat page that the board sends to the browser

Upload and Test

  1. First time with this board? Set it up with ESP32 Uno - Getting Started before you continue.
  2. Plug in the USB Type-C cable between the ESP32 Uno and your computer.
  3. Open Arduino IDE on your computer.
  4. Select the board: pick ESP32 Dev Module and the COM port of the board (CH340).
  5. Open the Library Manager with the icon on the left side of Arduino IDE.
  6. Install the web server library: search for DIYables ESP32 WebServer and click Install on the library from DIYables.
  • Search for DIYables ESP32 WebServer created by DIYables.io and click the Install button.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32 Dev Module
Library Manager
Type:
All
Topic:
All
DIYables ESP32 WebServer by DIYables.io
DIYables ESP32 WebServer library designed for ESP32 boards. It includes multi-page web server capabilities and WebSocket support for real-time communication, perfect for IoT projects and DIYables ESP32 boards. More info
1.0.1
INSTALL
Newbiely.ino
···
1 void setup() {
Output
Serial Monitor
Ln 1, Col 1
ESP32 Dev Module on COM15
1
  1. Create a sketch: make a new sketch and save it as, for example, newbiely.com.ino
  2. Paste the main code below into it.
/* * This ESP32 Uno code was developed by newbiely.com * * This ESP32 Uno code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp32-uno/esp32-uno-websocket */ #include <DIYables_ESP32_WebServer.h> #include "index.h" // put your own network name and password here const char WIFI_SSID[] = "YOUR_WIFI_SSID"; const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD"; // the HTTP server (port 80) and a pointer to its WebSocket server DIYables_ESP32_WebServer server; DIYables_ESP32_WebSocket* webSocket; // serves the chat page when a browser opens the board's IP address void handleHome(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) { // HTML_CONTENT is defined in the index.h tab server.sendResponse(client, HTML_CONTENT); } // called when a browser opens the WebSocket link void onWebSocketOpen(net::WebSocket& ws) { Serial.println("New WebSocket connection"); // greeting text kept for reference (it is not sent) const char welcome[] = "Connected to ESP32 Uno WebSocket Server!"; } // called each time the browser sends a text message void onWebSocketMessage(net::WebSocket& ws, const net::WebSocket::DataType dataType, const char* message, uint16_t length) { Serial.print("WebSocket Received ("); Serial.print(length); Serial.print(" bytes): "); Serial.println(message); // answer every connected browser with the same text if (webSocket != nullptr) { String response = "Received: " + String((char*)message); webSocket->broadcastTXT(response); Serial.print("WebSocket sent ("); Serial.print(response.length()); Serial.print(" bytes): "); Serial.println(response); } } // called when the browser closes the link void onWebSocketClose(net::WebSocket& ws, const net::WebSocket::CloseCode code, const char* reason, uint16_t length) { Serial.println("WebSocket client disconnected"); } void setup() { Serial.begin(9600); delay(1000); Serial.println("ESP32 Uno Web Server and WebSocket Server"); // map the "/" address to the page handler server.addRoute("/", handleHome); // join WiFi and start the HTTP server server.begin(WIFI_SSID, WIFI_PASSWORD); // start the WebSocket server on port 81 webSocket = server.enableWebSocket(81); if (webSocket != nullptr) { // attach the three event callbacks webSocket->onOpen(onWebSocketOpen); webSocket->onMessage(onWebSocketMessage); webSocket->onClose(onWebSocketClose); } else { Serial.println("Failed to start WebSocket server"); } } void loop() { // serve pending HTTP requests server.handleClient(); // process WebSocket traffic server.handleWebSocket(); }
  1. Enter your WiFi details: replace YOUR_WIFI_SSID and YOUR_WIFI_PASSWORD in the code with your own network name and password.
  2. Add the index.h tab: click the button under the Serial Monitor icon and choose New Tab, or press Ctrl+Shift+N.
Arduino IDE 2 adds file
  1. Name it index.h and click OK.
Arduino IDE 2 adds file index.h
  1. Paste the page code into index.h.
/* * This ESP32 Uno code was developed by newbiely.com * * This ESP32 Uno code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp32-uno/esp32-uno-websocket */ const char *HTML_CONTENT = R"=====( <!DOCTYPE html> <!-- saved from url=(0019)http://192.168.0.2/ --> <html><head><meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> <title>ESP32 Uno WebSocket</title> <meta name="viewport" content="width=device-width, initial-scale=0.7"> <link rel="icon" href="https://diyables.io/images/page/diyables.svg"> <style> /* Add some basic styling for the chat window */ body { font-size: 16px; } .chat-container { width: 400px; margin: 0 auto; padding: 10px; } .chat-messages { height: 250px; overflow-y: auto; border: 1px solid #444; padding: 5px; margin-bottom: 5px; } .user-input { display: flex; margin-bottom: 20px; } .user-input input { flex: 1; border: 1px solid #444; padding: 5px; } .user-input button { margin-left: 5px; background-color: #007bff; color: #fff; border: none; padding: 5px 10px; cursor: pointer; } .websocket { display: flex; align-items: center; margin-bottom: 5px; } .websocket button { background-color: #007bff; color: #fff; border: none; padding: 5px 10px; cursor: pointer; } .websocket .label { margin-left: auto; } </style> <script> var ws; var wsm_max_len = 4096; /* bigger length causes uart0 buffer overflow with low speed smart device */ function update_text(text) { var chat_messages = document.getElementById("chat-messages"); chat_messages.innerHTML += text + '<br>'; chat_messages.scrollTop = chat_messages.scrollHeight; } function send_onclick() { if(ws != null) { var message = document.getElementById("message").value; if (message) { document.getElementById("message").value = ""; ws.send(message + "\n"); update_text('<span style="color:navy">' + message + '</span>'); // You can send the message to the server or process it as needed } } } function connect_onclick() { if(ws == null) { ws = new WebSocket("ws://" + window.location.host + ":81"); document.getElementById("ws_state").innerHTML = "CONNECTING"; ws.onopen = ws_onopen; ws.onclose = ws_onclose; ws.onmessage = ws_onmessage; } else ws.close(); } function ws_onopen() { document.getElementById("ws_state").innerHTML = "<span style='color:blue'>CONNECTED</span>"; document.getElementById("bt_connect").innerHTML = "Disconnect"; document.getElementById("chat-messages").innerHTML = ""; } function ws_onclose() { document.getElementById("ws_state").innerHTML = "<span style='color:gray'>CLOSED</span>"; document.getElementById("bt_connect").innerHTML = "Connect"; ws.onopen = null; ws.onclose = null; ws.onmessage = null; ws = null; } function ws_onmessage(e_msg) { e_msg = e_msg || window.event; // MessageEvent console.log(e_msg.data); update_text('<span style="color:blue">' + e_msg.data + '</span>'); } </script> </head> <body> <div class="chat-container"> <h2>ESP32 Uno WebSocket</h2> <div class="websocket"> <button class="connect-button" id="bt_connect" onclick="connect_onclick()">Connect</button> <span class="label">WebSocket: <span id="ws_state"><span style="color:blue">CLOSED</span></span></span> </div> <div class="chat-messages" id="chat-messages"></div> <div class="user-input"> <input type="text" id="message" placeholder="Type your message..."> <button onclick="send_onclick()">Send</button> </div> <div class="sponsor">Sponsored by <a href="https://amazon.com/diyables">DIYables</a></div> </div> </body></html> )=====";
  1. Upload: you now have newbiely.com.ino and index.h. Click the Upload button. If the upload says "Waiting for download", hold the BOOT button on the board until it starts.
  2. Open the Serial Monitor and read the IP address of the board.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32 Dev Module' on 'COM15')
New Line
9600 baud
ESP32 Uno Web Server and WebSocket Server Connecting to WiFi... Connected to WiFi ESP32 Uno Web Server's IP address: 192.168.1.47 New WebSocket connection WebSocket Received (5 bytes): hello WebSocket sent (16 bytes): Received: hello
Ln 11, Col 1
ESP32 Dev Module on COM15
2
  1. Open the page: type that IP address in the address bar of a browser on your phone or PC (both must use the same WiFi).
ESP32 Uno websocket web browser
  1. Click Connect, type a short message and press Send. The board replies right away.
ESP32 Uno websocket chat server
  1. Pro tip: open the page on two devices at once. Because the code uses a broadcast, both chat windows show every reply.

※ NOTE THAT:

  • If you change only the HTML in index.h, Arduino IDE may skip it and upload the old page.
  • To force an update, change newbiely.com.ino a little, for example add an empty line or a comment.

How the System Works

Goal: follow one message from the browser to the board and back.

Step What Happens
1 You type the board IP address in the browser
2 The web server on the ESP32 Uno sends the page (HTML, CSS, JavaScript)
3 The browser shows the page
4 You click Connect, and the page script opens a WebSocket to port 81
5 You click Send, and the script pushes your text through the open link
6 The board gets the text and broadcasts a reply that the page prints

The web page itself uses port 80, and the WebSocket uses port 81.

See the ESP32 Uno build in action in the video below.

Code Explanation

Goal: know what each part of the sketch does. The comments in the code explain every line too.

Code Part What It Does
handleHome() Sends the chat page from index.h to the browser
onWebSocketOpen() Runs when a browser connects and prints a note
onWebSocketMessage() Prints the received text and broadcasts "Received ..." to all clients
onWebSocketClose() Runs when the browser disconnects
server.enableWebSocket(81) Starts the WebSocket server on port 81
server.handleClient() and server.handleWebSocket() Called in loop() to serve pages and messages

The result: every text you send comes back as a reply on the chat page.

ESP32 Uno vs UNO R4 for This Project

Goal: see what changes when you move this chat from the UNO R4 WiFi to the ESP32 Uno.

Item Arduino UNO R4 ESP32 Uno
Logic voltage 5V 3.3V
Wiring None None
WiFi Built-in module Built-in WiFi
Web server library Web Server for Arduino Uno R4 WiFi DIYables ESP32 WebServer
Main header file UnoR4WiFi_WebServer.h DIYables_ESP32_WebServer.h
Reply method Sends to the one client Broadcasts to all clients
Arduino IDE board Arduino UNO R4 WiFi ESP32 Dev Module

No wires are involved, so nothing needs rewiring. Just install the other library and pick the right board. The ESP32 Uno also needs no firmware update of the WiFi module.

Try These Next

  • Replace the echo reply with a command parser, for example "on" and "off" to switch an LED on D13 (GPIO18).
  • Send a sensor value to the page every second.
  • Study more WebSocket projects: ESP32 Uno - controls Robot Car via Web

Troubleshooting

Problem Possible Cause Solution
No COM port shows up CH340 driver missing or charge-only cable Install the CH340 driver and use a USB cable that carries data
Upload fails with "Failed to connect" or "Waiting for download" Board is not in download mode Hold the BOOT button while the upload starts
Board does not join WiFi Wrong SSID or password in the code Replace YOUR_WIFI_SSID and YOUR_WIFI_PASSWORD with the real values
No IP address in the Serial Monitor Wrong baud rate Set the Serial Monitor to 9600
Page does not open Phone or PC is on another network Use the same WiFi as the board
Connect button stays on CONNECTING Port 81 blocked or board reset Reload the page and check the board is still running
HTML changes do not show Only index.h was changed Edit newbiely.com.ino a little and upload again
Compile error about DIYables_ESP32_WebServer.h Library not installed Install DIYables ESP32 WebServer in Library Manager
Board resets often Weak USB power Use a good cable or another USB port

FAQ

What is a WebSocket used for on the ESP32 Uno?

It gives a browser a live two-way link to the board. You can control outputs or watch sensor data in real time without reloading the page.

Which port does the WebSocket server use?

This sketch uses port 81 for the WebSocket and port 80 for the web page. You can pick another number in enableWebSocket().

Do I need any extra hardware for this tutorial?

No. The ESP32 Uno form board has WiFi built in. You only need a USB Type-C cable and a WiFi network.

Why is the page stored in a separate index.h file?

It keeps the long HTML out of the main sketch, so the code stays easy to read and edit.

Will two phones or PCs work with the chat together?

Yes. The reply is broadcast, so every connected browser sees it.

Can I use a phone to open the page?

Yes. Any device on the same WiFi can open the IP address of the board in its browser.

Does the ESP32 Uno need a WiFi firmware update like the UNO R4 WiFi?

No. The firmware update step is only for the UNO R4 WiFi module. Check your credentials and board selection instead.

Can I use 5V modules with this project later?

Be careful. ESP32 Uno pins use 3.3V logic and are not 5V tolerant, so use a level shifter for 5V signals.

How do I control an LED from the chat page?

Read the received text in onWebSocketMessage() and call digitalWrite() on a pin such as D13 (GPIO18) when you get a word like "on" or "off".

Where do I find extra GPIO pins if the Uno headers run out?

The ESP32 Uno has extra holes near the power header: GPIO32 and GPIO33 (I/O, PWM, analog on ADC1, so they work while WiFi is on) and GPIO15 (I/O, PWM, analog on ADC2). Solder pin headers to use them and write the GPIO number in code. For a WiFi project with an analog sensor, GPIO32 or GPIO33 are the best picks. Warning 1: GPIO15 and GPIO0 (the IO0 pin at the unused Uno NC position) are boot strapping pins, and a wrong connection can stop the board from booting or uploading code, so use GPIO32 and GPIO33 first. Warning 2: never use the six holes under the digital header (SD0-SD3, CMD, CLK = GPIO6-GPIO11). They are wired to the flash chip and using them crashes the board.

※ OUR MESSAGES

  • As freelancers, We are AVAILABLE for HIRE. See how to outsource your project to us
  • Please feel free to share the link of this tutorial. However, Please do not use our content on any other websites. We invested a lot of effort and time to create the content, please respect our work!