Debugging Your ESP32 Project with a Serial Terminal
The ESP32 is a powerhouse microcontroller, beloved for its built-in Wi-Fi, Bluetooth, and dual-core processor. But with great power comes great complexity. When your ESP32 project isn't working—whether it's failing to connect to Wi-Fi or crashing unexpectedly—the serial terminal is your single most important debugging tool.
~7 minutes

The ESP32 is a powerhouse microcontroller, beloved for its built-in Wi-Fi, Bluetooth, and dual-core processor. But with great power comes great complexity. When your ESP32 project isn't working—whether it's failing to connect to Wi-Fi or crashing unexpectedly—the serial terminal is your single most important debugging tool.
The ESP32's Secret Language: The Boot Messages
Unlike a simple Arduino, the ESP32 prints a stream of diagnostic messages to the serial port every time it boots or resets. To see this, you need to set your serial terminal to the correct baud rate, which for the ESP32's bootloader is typically 115200.
If you connect to an ESP32 at 115200 baud and press its "RST" or "EN" button, you'll see something like this:
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:0x118c
load:0x40078000,len:0x13134
load:0x40080400,len:0x3a6c
entry 0x40080698
This is the bootloader telling you exactly how it's starting up. Seeing this message is your first "hello world"—it confirms your board is alive and your serial connection is working. If you see garbled text (G⸮J⸮), your baud rate is wrong. This is a common issue covered in our guide on troubleshooting serial connections can help.
After these messages, your own application's code begins to run.
Basic Debugging with Serial.printf
Just like with Arduino, you can print messages from your own code. The ESP32 framework (whether using the Arduino core or ESP-IDF) provides a powerful printf function for formatted output. To make your logs even more readable, you can use ANSI colors to make your logs readable.
Here's a more robust example for the Arduino IDE that demonstrates different log levels and intentionally causes a crash.
#include <WiFi.h>
// Define some ANSI color codes to make logs more readable
#define ANSI_COLOR_GREEN "\x1b[32m"
#define ANSI_COLOR_YELLOW "\x1b[33m"
#define ANSI_COLOR_RED "\x1b[31m"
#define ANSI_COLOR_RESET "\x1b[0m"
const char* ssid = "Your_WiFi_SSID";
const char* password = "Your_WiFi_Password";
void setup() {
Serial.begin(115200);
delay(100); // Allow time for serial to initialize
Serial.printf("INFO: Booting up... Chip-ID: %llX\n", ESP.getEfuseMac());
Serial.printf("INFO: Connecting to %s ", ssid);
WiFi.begin(ssid, password);
int retries = 0;
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
if (retries++ > 20) {
Serial.printf("\n" ANSI_COLOR_YELLOW "WARN: Could not connect to WiFi after 10 seconds." ANSI_COLOR_RESET "\n");
break;
}
}
if (WiFi.status() == WL_CONNECTED) {
Serial.printf("\n" ANSI_COLOR_GREEN "SUCCESS: WiFi connected!" ANSI_COLOR_RESET "\n");
Serial.print("INFO: IP address: ");
Serial.println(WiFi.localIP());
}
// This will cause a crash
Serial.printf(ANSI_COLOR_RED "ERROR: About to cause a deliberate crash by dereferencing a null pointer." ANSI_COLOR_RESET "\n");
delay(1000);
int *ptr = NULL;
*ptr = 42; // This line will trigger a Guru Meditation Error
}
void loop() {
// Your main code here
}
Expected Output
When you run this code, the serial terminal becomes your mission control center. You'll see a much richer output that demonstrates a typical debugging workflow.
- First, the standard ESP32 bootloader messages appear.
- Then, your application's custom logs start printing.
- If it connects to Wi-Fi successfully, you'll see the green success message.
- Finally, it will print the error message and then crash, producing the Guru Meditation Error report.
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
...
entry 0x40080698
INFO: Booting up... Chip-ID: 1234567890AB
INFO: Connecting to Your_WiFi_SSID ......
SUCCESS: WiFi connected!
INFO: IP address: 192.168.1.123
ERROR: About to cause a deliberate crash by dereferencing a null pointer.
Guru Meditation Error: Core 1 panic'ed (StoreProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x400d1a2b PS : 0x00060d30 A0 : 0x800d1b6c A1 : 0x3ffb1f90
A2 : 0x00000000 A3 : 0x0000002a A4 : 0x00000000 A5 : 0x3ffb8058
...
Backtrace: 0x400d1a28:0x3ffb1f90 0x400d1b69:0x3ffb1fb0 0x400d1bb1:0x3ffb1fd0 0x40088215:0x3ffb1ff0
Rebooting...
If it gets stuck on the dots, the warning message will inform you that it failed to connect, giving you a clear indication of a network problem.
Understanding Crash Reports (Guru Meditation Error)
Sometimes your ESP32 will crash and reset. When this happens, it often prints a "Guru Meditation Error" report to the serial port just before it reboots. It looks like a terrifying block of hexadecimal numbers:
Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled.
Core 0 register dump:
PC : 0x400d12a4 PS : 0x00060030 A0 : 0x800d12b0 A1 : 0x3ffb1f70
A2 : 0x00000000 A3 : 0x3ffb1f9c A4 : 0x000000ff A5 : 0x0000ff00
...
Backtrace: 0x400d12a1:0x3ffb1f70 0x400d12ae:0x3ffb1f90 0x400d130e:0x3ffb1fb0 0x40088215:0x3ffb1fd0
Rebooting...
This is not random garbage! It's a crash dump. While decoding it is an advanced topic (requiring a tool called esp-exception-decoder), simply capturing this output in your serial terminal is the crucial first step. It tells you that a crash occurred and provides the evidence a developer needs to figure out why. For more details on advanced troubleshooting, see the official ESP-IDF Troubleshooting Guide.
A web serial terminal like serialterminal.app is perfect for this, as you can easily copy and paste this entire block of text into a forum post or a GitHub issue when asking for help.
From deciphering boot messages to catching crash reports, the serial terminal is the non-negotiable, indispensable tool for any serious ESP32 developer.