Integration Guide
Add a WebSerial remote terminal to an existing ESPAsyncWebServer sketch on ESP8266, ESP32, RP2040 or RP2350.
This guide shows how to add WebSerial to a sketch that already runs an AsyncWebServer. Each step lists the lines to add; the complete sketch is at the end of the page.
Include the dependencies
Include the Wi-Fi, async TCP and web server headers for your platform, followed by WebSerial.h. The preprocessor conditions below select the correct headers for each supported board, so the same sketch compiles on every platform.
#include <Arduino.h>
#if defined(ESP8266)
/* ESP8266 Dependencies */
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#elif defined(ESP32)
/* ESP32 Dependencies */
#include <WiFi.h>
#include <AsyncTCP.h>
#elif defined(TARGET_RP2040) || defined(PICO_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2350)
/* RP2040 or RP2350 Dependencies */
#include <WiFi.h>
#include <RPAsyncTCP.h>
#endif
#include <ESPAsyncWebServer.h>
#include <WebSerial.h>With WebSerial Pro, include WebSerialPro.h instead of WebSerial.h. WebSerial Pro supports ESP8266 and ESP32 only.
Create the web server
WebSerial uses AsyncWebServer to serve the terminal page and to handle the WebSocket connection. Create an instance on port 80, or on any other port you prefer.
AsyncWebServer server(80);Initialize WebSerial in setup()
Pass a pointer to the AsyncWebServer instance to WebSerial.begin(). Register an onMessage() callback to receive commands typed into the terminal, then start the server.
void setup() {
// ... existing setup code
// Attach WebSerial to the AsyncWebServer instance
WebSerial.begin(&server);
// Handle incoming messages from the terminal
WebSerial.onMessage([](uint8_t *data, size_t len) {
Serial.printf("Received %u bytes from WebSerial: ", len);
Serial.write(data, len);
Serial.println();
});
// Start AsyncWebServer
server.begin();
}The terminal is served at /webserial by default. Pass a different path as the second argument of begin() to change it, for example WebSerial.begin(&server, "/terminal").
Call WebSerial.loop() in loop()
In the default (buffered) mode, WebSerial.loop() flushes buffered output and cleans up disconnected clients. Call it on every iteration and keep loop() free of blocking code.
void loop() {
// ... existing loop code
WebSerial.loop();
}Open the terminal
Upload the sketch and open http://<device-ip>/webserial in a browser on the same network.
Complete example
#include <Arduino.h>
#if defined(ESP8266)
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#elif defined(ESP32)
#include <WiFi.h>
#include <AsyncTCP.h>
#elif defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350)
#include <WiFi.h>
#include <RPAsyncTCP.h>
#endif
#include <ESPAsyncWebServer.h>
#include <WebSerial.h>
AsyncWebServer server(80);
const char* ssid = ""; // Your Wi-Fi SSID
const char* password = ""; // Your Wi-Fi password
unsigned long last_print_time = millis();
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.printf("WiFi Failed!\n");
return;
}
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
// WebSerial is accessible at "<IP Address>/webserial"
WebSerial.begin(&server);
// Echo received messages back to the terminal
WebSerial.onMessage([](uint8_t *data, size_t len) {
Serial.printf("Received %u bytes from WebSerial: ", len);
Serial.write(data, len);
Serial.println();
WebSerial.println("Received Data...");
String d = "";
for (size_t i = 0; i < len; i++) {
d += char(data[i]);
}
WebSerial.println(d);
});
server.begin();
}
void loop() {
// Print every 2 seconds (non-blocking)
if ((unsigned long)(millis() - last_print_time) > 2000) {
WebSerial.print(F("IP address: "));
WebSerial.println(WiFi.localIP());
WebSerial.printf("Uptime: %lums\n", millis());
last_print_time = millis();
}
WebSerial.loop();
}Next steps
- Printing: methods for sending output to the terminal.
- Callbacks: handle commands received from the terminal.
- Authentication: restrict access to the terminal.