I’m using the Web Serial API to read data from an ESP32 device via a USB connection, but I consistently encounter the error “BufferOverrunError” in my browser when trying to read data.
Setup:
ESP32 is sending both text and JSON data intermittently.
Baud rate: 19200.
Browser: Chrome (latest version).
I’m using the API to request a port, connect, and continuously read data using read() in a loop.
Problem:
Despite the fact that the ESP32 is not sending large amounts of data (it’s mostly small JSON payloads or text), I keep running into BufferOverrunError on the browser side. I have tried:
Increasing the buffer size (bufferSize) when opening the port.
Adding pauses (setTimeout() or await pauses) to slow down the reading loop.
Processing data in smaller chunks.
None of these approaches have resolved the issue, and I still see the buffer overrun after a short time.
Here is my codes (ESP32 and JS)
ESP32 (Arduino IDE)
void setup() {
// put your setup code here, to run once:
Serial.begin(19200);
}
void loop() {
// put your main code here, to run repeatedly:
Serial.println("Hello");
delay(2000);
}
HTML/JS
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>USB Serial Port Connection</title>
</head>
<body>
<h1>Connect to USB Serial Port</h1>
<!-- Button to initiate USB serial connection -->
<button id="connectButton">Connect to USB</button>
<!-- Button to disconnect from USB, disabled by default -->
<button id="disconnectButton" disabled>Disconnect</button>
<!-- Container to display the data received from the serial port -->
<pre id="dataOutput"></pre>
<script>
let port, reader, isConnected = false;
// Function to handle connection to the USB serial port
async function connectSerialPort() {
try {
// Request the user to select a serial port (USB) from the available options
port = await navigator.serial.requestPort();
// Open the selected port with a baud rate of 115200
await port.open({ baudRate: 19200 });
// Get a reader to read data from the serial port
reader = port.readable.getReader();
// Set the connection status to true
isConnected = true;
// Disable the "Connect" button and enable the "Disconnect" button
document.getElementById('connectButton').disabled = true;
document.getElementById('disconnectButton').disabled = false;
// Start reading data from the serial port
readSerialData();
} catch (error) {
// Handle any errors that occur during the connection process
console.error('Error connecting to the serial port:', error);
}
}
// Function to handle disconnection from the USB serial port
async function disconnectSerialPort() {
if (reader) {
// Cancel and release the reader when disconnecting
await reader.cancel();
reader.releaseLock();
}
if (port) {
// Close the port to finish the disconnection process
await port.close();
}
// Reset the connection status to false
isConnected = false;
// Re-enable the "Connect" button and disable the "Disconnect" button
document.getElementById('connectButton').disabled = false;
document.getElementById('disconnectButton').disabled = true;
}
// Function to continuously read data from the serial port
async function readSerialData() {
// Create a TextDecoder to convert the raw data into text
const decoder = new TextDecoder();
while (isConnected) {
try {
// Read data from the serial port
const { value, done } = await reader.read();
// Stop reading if there is no more data
if (done) break;
// If data is received, decode it and append it to the output area
if (value) {
const decodedData = decoder.decode(value);
document.getElementById('dataOutput').textContent += decodedData;
}
} catch (error) {
// Handle any errors that occur during data reading
console.error('Error reading from the serial port:', error);
break;
}
}
}
// Event listeners for the Connect and Disconnect buttons
document.getElementById('connectButton').addEventListener('click', connectSerialPort);
document.getElementById('disconnectButton').addEventListener('click', disconnectSerialPort);
</script>
</body>
</html>
Questions:
What could be causing this BufferOverrunError on the browser side even with low data throughput?
Are there any strategies or best practices for handling serial data more efficiently using the Web Serial API to avoid buffer overflows?
Could this be related to how Chrome or the Web Serial API handles buffers, or is it something on the ESP32 side?
Any insights or suggestions would be greatly appreciated!