What Is the Arduino Core Debug Level?
The Arduino Core Debug Level is a compile-time configuration setting in the Arduino IDE (specifically for ESP32 and ESP8266 boards) that controls the verbosity of the underlying Real-Time Operating System (RTOS) logs printed to the hardware serial port. When you write code for an ESP32, you are actually building on top of Espressif’s ESP-IDF and FreeRTOS. The Core Debug Level dictates whether the Wi-Fi stack, Bluetooth controller, memory allocator, and TCP/IP adapter are allowed to print their internal state, warnings, and fatal errors to your Serial Monitor.
Unlike standard Serial.println() statements that you write manually, Core Debug logs are generated by the silicon vendor's底层 (底层 means underlying/low-level) libraries. If your ESP32 randomly reboots, fails to connect to Wi-Fi, or throws a Guru Meditation Error, setting the Core Debug Level to "Verbose" or "Debug" is the single most effective way to see exactly which internal function failed and why, without rewriting your application code.
esp_log_level_t enum. Changing this menu option alters the -DCORE_DEBUG_LEVEL compiler flag, which physically strips out or includes logging macros during the C++ preprocessor stage.
The 6 Core Debug Levels (Memory & Output Matrix)
Before flashing your board, you need to know the trade-offs. Higher debug levels consume more flash memory (storing the string literals) and take more CPU time to format and transmit over UART, which can cause watchdog timeouts in timing-critical loops.
| IDE Menu Option | ESP-IDF Enum | Hex/Int Value | Flash Overhead (Approx) | Serial Output Behavior & Use Case |
|---|---|---|---|---|
| None | ESP_LOG_NONE |
0 | 0 KB | No RTOS logs. Use for final production firmware to maximize free heap and flash space. |
| Error | ESP_LOG_ERROR |
1 | ~5 KB | Prints only critical failures (e.g., Wi-Fi auth fail, I2C bus lockup). Best for everyday development. |
| Warn | ESP_LOG_WARN |
2 | ~12 KB | Includes non-fatal anomalies (e.g., deprecated API usage, low heap warnings). Good for stability testing. |
| Info | ESP_LOG_INFO |
3 | ~25 KB | Standard operational logs (e.g., Wi-Fi connected, IP assigned, BLE advertising started). |
| Debug | ESP_LOG_DEBUG |
4 | ~45 KB | Detailed state transitions. Use when debugging handshake failures or deep sleep wake sources. |
| Verbose | ESP_LOG_VERBOSE |
5 | ~80+ KB | Trace-level packet dumps and memory allocations. Warning: Can flood the UART buffer and trigger Task Watchdog resets. |
For authoritative details on how Espressif handles these logging tags under the hood, refer to the official ESP-IDF Logging API documentation.
Hardware & Parts List for Debugging
To properly capture and analyze core debug logs, your hardware must support reliable high-speed UART communication. Brownouts or dropped packets on the serial line will corrupt the log output, making it unreadable.
- Microcontroller: ESP32-WROOM-32 DevKit v1 (30-pin or 38-pin variant). Ensure it has an integrated USB-UART bridge.
- USB-UART Bridge IC: CP2102 or CP2102N (preferred for stable 921600 baud drivers) or CH340G (common on budget clones, requires specific driver installation).
- USB Cable: High-quality USB-A to Micro-USB data cable with 22AWG power cores. Charge-only cables lack the D+/D- data lines required for serial debugging.
- External Power (Optional but recommended): 5V 2A bench power supply wired to the
5VandGNDpins if debugging high-current peripherals (like SIM800L or WS2812B strips) that cause USB brownouts.
Pin Mapping for Hardware Serial Debug
The ESP32 routes its default boot and debug logs to UART0. If you are using an external USB-to-TTL adapter (like an FTDI232) because your board's onboard bridge is fried, you must wire it to these exact GPIOs.
| ESP32 Pin | UART0 Function | FTDI Adapter Pin | Notes & Warnings |
|---|---|---|---|
| GPIO1 (TX0) | Transmit Data | RXD | ESP32 TX connects to Adapter RX. Level is 3.3V logic. |
| GPIO3 (RX0) | Receive Data | TXD | ESP32 RX connects to Adapter TX. Do not feed 5V logic here. |
| EN (CHIP_PU) | Chip Enable / Reset | DTR (via capacitor) | Required for auto-reset during upload. Pull low to reboot. |
| GND | Ground Reference | GND | Must share a common ground with the adapter and PC. |
Complete ESP32 Debug Logging Code
The following code targets the ESP32 DevKit v1 (ESP32-WROOM-32). It demonstrates how to use the ESP-IDF logging macros (log_i, log_w, log_e) alongside standard Arduino functions. It includes error handling for Wi-Fi connection and a simulated sensor fault to trigger core-level error logs.
Note: Ensure your Arduino IDE is set to Tools > Core Debug Level: Info (or higher) before compiling this sketch.
#include <WiFi.h>
// --- Pin Definitions ---
#define PIN_STATUS_LED 2 // Built-in LED on most DevKit v1 boards
#define PIN_SENSOR_PWR 4 // Power pin for external sensor
#define PIN_SENSOR_DATA 34 // ADC input for sensor (Input only)
// --- Network Credentials ---
const char* ssid = "YourNetworkSSID";
const char* password = "YourNetworkPassword";
// --- Custom Log Tag ---
static const char* TAG = "APP_MAIN";
void setup() {
// Initialize hardware serial for debug output
Serial.begin(115200);
delay(500); // Allow serial monitor to attach
pinMode(PIN_STATUS_LED, OUTPUT);
pinMode(PIN_SENSOR_PWR, OUTPUT);
log_i("System booting... Free heap: %d bytes", ESP.getFreeHeap());
// Power up the sensor
digitalWrite(PIN_SENSOR_PWR, HIGH);
log_d("Sensor power rail enabled on GPIO %d", PIN_SENSOR_PWR);
// Attempt Wi-Fi Connection with error handling
connectToWiFi();
}
void loop() {
// Read simulated sensor data
int sensorValue = analogRead(PIN_SENSOR_DATA);
if (sensorValue == 0) {
// Trigger an Error level log (visible at Error, Warn, Info, Debug, Verbose)
log_e("Sensor fault detected! Read 0 on GPIO %d. Check wiring.", PIN_SENSOR_DATA);
digitalWrite(PIN_STATUS_LED, HIGH); // Solid LED on error
delay(2000);
} else if (sensorValue > 3000) {
// Trigger a Warning level log
log_w("Sensor reading high: %d. Possible thermal drift.", sensorValue);
blinkLED(3);
} else {
// Trigger an Info level log
log_i("Sensor nominal. Value: %d", sensorValue);
blinkLED(1);
}
// Trigger a Verbose level log (only visible if Core Debug Level is Verbose)
log_v("Loop iteration complete. Uptime: %lu ms", millis());
delay(1000);
}
void connectToWiFi() {
log_i("Attempting connection to SSID: %s", ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 20) {
delay(500);
Serial.print(".");
attempts++;
}
if (WiFi.status() == WL_CONNECTED) {
log_i("Connected! IP Address: %s", WiFi.localIP().toString().c_str());
} else {
log_e("Wi-Fi connection failed. Error code: %d", WiFi.status());
// Blink LED rapidly to indicate network failure
for(int i=0; i<10; i++) {
digitalWrite(PIN_STATUS_LED, !digitalRead(PIN_STATUS_LED));
delay(100);
}
}
}
void blinkLED(int times) {
for(int i=0; i<times; i++) {
digitalWrite(PIN_STATUS_LED, HIGH);
delay(150);
digitalWrite(PIN_STATUS_LED, LOW);
delay(150);
}
}
Troubleshooting: When Core Debug Output Fails
When working with deep RTOS logs, you will eventually encounter situations where the serial output stops, turns to garbage, or throws a specific ESP-IDF error.
Exact Error String: E (345) wifi: wifi_init 123: esp_err_t 0x3001 (Followed by a reboot or silent hang).
Ranked Causes:
- Heap Exhaustion (Most Likely): Error
0x3001isESP_ERR_NO_MEM. Enabling "Verbose" core debug level consumes significant RAM for log buffers. If you are also initializing BLE and Wi-Fi simultaneously, the ESP32 runs out of internal SRAM. - PSRAM Not Enabled: If your board has external PSRAM (e.g., ESP32-CAM or WROVER) but the Arduino IDE menu has "PSRAM: Disabled", the Wi-Fi stack cannot allocate its required RX/TX buffers.
- UART Buffer Overflow: At "Verbose" level, the RTOS prints faster than the 115200 baud serial port can transmit, causing the UART FIFO buffer to overflow and drop packets or lock the CPU.
- Verify the Menu Selection Actually Saved: The Arduino IDE frequently resets the "Core Debug Level" back to "None" when you switch board variants or close the IDE. Always check Tools > Core Debug Level immediately before hitting Upload.
- Match the Baud Rate: The ESP32 bootloader prints at 115200 baud, but some custom ESP-IDF configurations push the RTOS log baud rate to 921600. If your Serial Monitor is set to 115200 and you see garbage characters like
ets Jun 8 2016...followed by symbols, change your monitor baud rate to 921600. - Check the USB Cable & Port: A failing USB cable will cause voltage drops when the Wi-Fi radio transmits (spiking to 350mA). This triggers the brownout detector, resetting the chip before the error log can finish transmitting. Use a powered USB hub or a shorter, thicker cable.
Extending and Simplifying Your Debug Build
Once you have identified the root cause of your bug, leaving the Core Debug Level on "Verbose" is a liability. It bloats your binary size, slows down your main loop, and exposes internal state if the serial port is physically accessible in the field.
How to Simplify for Production:
- Set the IDE menu to None. This strips all
log_*macros from the compiled binary via the preprocessor, recovering up to 80KB of flash space and eliminating UART blocking delays. - Replace RTOS logs with lightweight custom flags. Instead of
log_i(), use a single byte status register that you can read via I2C or BLE from a master controller.
How to Extend for Advanced Filtering:
If you need Wi-Fi debug logs but want to silence the Bluetooth stack to save CPU cycles, the Arduino IDE menu is too blunt an instrument. You must use the ESP-IDF sdkconfig file or runtime API. You can dynamically change the log level for specific components in your setup() function using the esp_log_level_set() function:
#include <esp_log.h>
void setup() {
// Silence Bluetooth controller logs at runtime
esp_log_level_set("BT_CONTROLLER", ESP_LOG_NONE);
// Keep Wi-Fi logs at Debug level
esp_log_level_set("wifi", ESP_LOG_DEBUG);
// Keep your custom app tag at Info
esp_log_level_set("APP_MAIN", ESP_LOG_INFO);
}
For more advanced project configurations and custom board definitions, consult the official Arduino-ESP32 GitHub repository, which details how to create custom boards.txt entries with pre-baked debug levels for manufacturing workflows.






