Home / Tutorials / ESP32 Tutorial / Arduino ESP32 Autobaud Example: Detect UART Baud Rate Automatically
pcbway
Arduino ESP32 autobaud example

Arduino ESP32 Autobaud Example: Detect UART Baud Rate Automatically

If you are connecting an ESP32 to a UART device, both sides normally need to use the same baud rate. For example, if your external module is sending data at 9600 baud but your ESP32 is listening at 115200 baud, the data will not be read correctly.

Fortunately, some ESP32 chips support automatic baud rate detection. In this Arduino ESP32 autobaud example, we’ll use the Arduino-ESP32 Serial API to detect the baud rate of incoming UART data automatically.

This is useful when working with unknown serial devices, AT command modules, GPS modules, GSM modules, Bluetooth serial modules, or any UART device where the baud rate is not immediately known.


What Is Autobaud?

Autobaud is a feature that allows a UART peripheral to detect the baud rate of incoming serial data.

Instead of writing:

Serial.begin(9600);

or:

Serial.begin(115200);

you can start the serial port with a baud rate of 0 on supported ESP32 chips:

Serial.begin(0);

This tells the ESP32 to wait for incoming UART data and try to determine the correct baud rate automatically.


Important: ESP32 Autobaud Is Not Supported on All ESP32 Chips

According to the Arduino-ESP32 Serial API, baud rate detection is supported only on:

  • ESP32
  • ESP32-S2

It does not work on all newer ESP32 variants such as ESP32-C3, ESP32-S3, ESP32-C6, and other SoCs.

This is important because many boards are called “ESP32” even if they use a different chip. For example:

Board / Chip Autobaud Support
ESP32-WROOM-32 Yes
ESP32-S2 Yes
ESP32-S3 No
ESP32-C3 No
ESP32-C6 No

So before using this feature, check the actual chip on your board.


Basic Arduino ESP32 Autobaud Example

Here is the simplest Arduino ESP32 autobaud example:

void setup() {
  Serial.begin(0);

  Serial.print("Detected baud rate: ");
  Serial.println(Serial.baudRate());

  if (Serial.baudRate() == 0) {
    Serial.end();
    Serial.begin(115200);
    delay(1000);

    Serial.println("Baud rate detection failed.");
    Serial.println("Serial reset to 115200.");
  }
}

void loop() {
}

In this example, Serial.begin(0) starts baud rate detection.

The ESP32 waits for incoming serial data. If it detects the baud rate successfully, Serial.baudRate() returns the detected baud rate.

If detection fails, Serial.baudRate() returns 0. The sketch then restarts Serial at 115200 baud so you can still see a message in the Arduino Serial Monitor.


How to Test ESP32 Autobaud

To test this sketch, upload it to an ESP32 or ESP32-S2 board.

Then open the Arduino IDE Serial Monitor and choose a baud rate such as:

  • 9600
  • 19200
  • 38400
  • 57600
  • 115200

Type a few characters and send them.

The ESP32 should detect the baud rate and print the detected value.

The detected value may not always be exactly the same number. For example, 115200 may appear as 115201. This small difference is normal.


Autobaud on Serial1 or Serial2

In many real projects, you probably do not want to use Serial for autobaud because Serial is usually connected to the USB port and used for debugging.

Instead, you can use Serial1 or Serial2 for the external UART device.

Here is an example using Serial2 on GPIO16 and GPIO17:

#define RXD2 16
#define TXD2 17

void setup() {
  Serial.begin(115200);
  delay(1000);

  Serial.println("Arduino ESP32 Autobaud Example on Serial2");
  Serial.println("Waiting for incoming UART data...");

  Serial2.begin(0, SERIAL_8N1, RXD2, TXD2, false, 20000);

  uint32_t detectedBaud = Serial2.baudRate();

  if (detectedBaud == 0) {
    Serial.println("Baud rate detection failed.");
    Serial.println("Make sure the external device is sending data.");
  } else {
    Serial.print("Detected baud rate: ");
    Serial.println(detectedBaud);
  }
}

void loop() {
  while (Serial2.available()) {
    Serial.write(Serial2.read());
  }
}

This sketch uses:

Serial2.begin(0, SERIAL_8N1, RXD2, TXD2, false, 20000);

The first parameter is 0, which enables baud rate detection.

The last parameter, 20000, is the timeout in milliseconds. That means the ESP32 waits up to 20 seconds for incoming data.


ESP32 Serial2 Wiring

For the example above, connect the external UART device like this:

ESP32 Pin External UART Device
GPIO16 RX2 TX
GPIO17 TX2 RX
GND GND

Make sure both devices share a common ground.

Also remember that the ESP32 uses 3.3V logic. If the external device uses 5V UART signals, use a logic level shifter or voltage divider before connecting to the ESP32 RX pin.


Example: ESP32 Autobaud Serial Bridge

After detecting the baud rate, you can use the ESP32 as a simple USB-to-UART bridge.

#define RXD2 16
#define TXD2 17

void setup() {
  Serial.begin(115200);
  delay(1000);

  Serial.println();
  Serial.println("ESP32 Autobaud Serial Bridge");
  Serial.println("Waiting for external UART data...");

  Serial2.begin(0, SERIAL_8N1, RXD2, TXD2, false, 20000);

  uint32_t baud = Serial2.baudRate();

  if (baud == 0) {
    Serial.println("Autobaud failed. Restarting Serial2 at 9600.");
    Serial2.end();
    Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);
  } else {
    Serial.print("Detected baud rate: ");
    Serial.println(baud);
  }

  Serial.println("Bridge ready.");
}

void loop() {
  while (Serial.available()) {
    Serial2.write(Serial.read());
  }

  while (Serial2.available()) {
    Serial.write(Serial2.read());
  }
}

This is useful for testing UART modules. Once the ESP32 detects the baud rate, anything you type in the Serial Monitor is forwarded to the external device. Any response from the external device is printed back to the Serial Monitor.


Using ESP32 Autobaud with AT Command Modules

Autobaud is useful for AT command modules because some modules may be configured to different baud rates.

Examples include:

  • GSM modules
  • Bluetooth serial modules
  • Wi-Fi modem modules
  • LoRa UART modules
  • GPS modules with command interfaces

After detecting the baud rate, you can send an AT command:

Serial2.println("AT");

Then read the response:

if (Serial2.available()) {
  String response = Serial2.readString();
  Serial.println(response);
}

If the module replies with:

OK

then your wiring and baud rate are likely correct.


Why Autobaud Detection May Fail

Autobaud detection needs incoming UART data. If the external device is silent during the timeout period, the ESP32 will not be able to detect the baud rate.

Detection may fail if:

  • The connected device is not sending data
  • RX and TX are wired incorrectly
  • GND is not connected
  • The UART signal level is wrong
  • The selected ESP32 chip does not support autobaud
  • The baud rate is outside the supported detection range
  • The signal is noisy or inverted

For testing, use a device that repeatedly sends text data.


Fallback Method for ESP32-C3, ESP32-S3, and Other Chips

If your ESP32 chip does not support Serial.begin(0) autobaud detection, you can still make a software-style workaround by scanning common baud rates.

This is not true hardware autobaud, but it can work if the device sends readable text.

#define RXD2 16
#define TXD2 17

const long baudRates[] = {
  9600,
  19200,
  38400,
  57600,
  115200,
  230400
};

const int baudCount = sizeof(baudRates) / sizeof(baudRates[0]);

bool looksReadable(String data) {
  int readable = 0;

  for (int i = 0; i < data.length(); i++) {
    char c = data[i];

    if ((c >= 32 && c <= 126) || c == '\r' || c == '\n') {
      readable++;
    }
  }

  return data.length() > 0 && readable > data.length() * 0.8;
}

long scanBaudRate() {
  for (int i = 0; i < baudCount; i++) {
    long baud = baudRates[i];

    Serial.print("Testing ");
    Serial.println(baud);

    Serial2.end();
    delay(100);
    Serial2.begin(baud, SERIAL_8N1, RXD2, TXD2);
    delay(300);

    String sample = "";
    unsigned long start = millis();

    while (millis() - start < 1000) {
      while (Serial2.available()) {
        sample += (char)Serial2.read();
      }
    }

    if (looksReadable(sample)) {
      return baud;
    }
  }

  return -1;
}

void setup() {
  Serial.begin(115200);
  delay(1000);

  Serial.println("Software baud scan fallback example");

  long baud = scanBaudRate();

  if (baud > 0) {
    Serial.print("Likely baud rate: ");
    Serial.println(baud);

    Serial2.end();
    Serial2.begin(baud, SERIAL_8N1, RXD2, TXD2);
  } else {
    Serial.println("Could not detect baud rate.");
  }
}

void loop() {
  while (Serial2.available()) {
    Serial.write(Serial2.read());
  }
}

Use this fallback method only when the hardware autobaud feature is not available.


Hardware Autobaud vs Baud Rate Scanning

Method Best For Notes
Serial.begin(0) ESP32 and ESP32-S2 Uses Arduino-ESP32 baud detection
Manual baud scanning ESP32-C3, ESP32-S3, and other chips Software workaround
Fixed baud rate Known devices Most reliable option

If you already know the baud rate, use a fixed baud rate. Autobaud is mainly useful when the baud rate is unknown.


Final Thoughts

This Arduino ESP32 autobaud example shows how to detect the UART baud rate automatically using the Arduino-ESP32 Serial API.

On supported chips, such as ESP32 and ESP32-S2, you can call:

Serial.begin(0);

or:

Serial2.begin(0, SERIAL_8N1, RXD2, TXD2);

Then read the detected baud rate using:

Serial.baudRate();

For unsupported ESP32 variants, such as ESP32-C3 or ESP32-S3, use a manual baud-rate scanning method instead.

Autobaud is not needed for every project, but it is very useful when debugging unknown UART devices or building flexible ESP32 serial tools.

Check Also

BLE WiFi concurrency using RTOS

Solving BLE and Wi-Fi Concurrency on ESP32 Using FreeRTOS

Updated: January 27, 2026Running Bluetooth Low Energy (BLE) scanning and Wi-Fi networking at the same …

Index