ESP32 Bench
Boards: ESP32, S3, C3
Flash and monitor: Web Serial

Hall of flames

Failures worth remembering: what the serial port said, what it is easy to mistake that for, and what was actually wrong. 6 of these come from ProbeHarbor's hardware test log and use the status lines recorded there. The rest are common ESP32 failures, shown with typical output.

Exhibit 01

The sensor that was found but would not read

ESP32-S3-DevKitC-1From ProbeHarbor's tests
TT sensor: AHT20 on I2C (SDA 8, SCL 9)
TT sensor problem: AHT20 found but not reading: no data after the measure command
Easy to mistake for
A firmware bug. The older firmware even reported a missing probe on GPIO 4, which pointed at the wrong sensor.
Was
A loose ground pin on the sensor, noted in the test log as the likely cause.
Fix
Reseat power and ground first whenever a sensor is detected but returns nothing.

What the bench's crash translator says about this log: ProbeHarbor: a sensor that is found but will not read usually has a loose power or ground wire.

Exhibit 02

Wi-Fi fine, no reading

ESP32-C3-DevKitM-1From ProbeHarbor's tests
TT key saved
TT wifi ok
Easy to mistake for
A dead DHT22, or firmware that did not support the C3.
Was
The data wire was on the wrong header pad. The C3's pad order is nothing like the classic ESP32's.
Fix
Read the silkscreen, not the position. Once the wire moved to the pad marked 4 the log read: TT sensor: DHT22 on GPIO 4.
Exhibit 03

The board that booted and said nothing

ESP32-C3 on its native USB portFrom ProbeHarbor's tests
(no output at all)
Easy to mistake for
A failed flash or a bad cable.
Was
The build left native USB serial off. The firmware ran, but its output went to UART pins nobody was listening on, and settings sent over USB were ignored.
Fix
ProbeHarbor fixed it in firmware 1.2.5 by building the C3 image with -DARDUINO_USB_MODE=1.
Exhibit 04

The upload that failed and succeeded

ESP32-S3-DevKitC-1From ProbeHarbor's tests
TT wifi ok
TT post -5 probes=1
TT post -5 probes=1
TT waiting for wifi
Easy to mistake for
Readings were being lost.
Was
-5 is the HTTP client's code for a lost connection. The reply was dropped on the way back; the server had stored both readings.
Fix
Check the server before trusting a client-side error. Treat -5 as unknown, not failed.

What the bench's crash translator says about this log: ProbeHarbor: -5 means the reply was lost, not the reading. The server usually has it.

Exhibit 05

Flashed an update, lost the Wi-Fi

Any board flashed from the browserFrom ProbeHarbor's tests
TT firmware 1.2.6
TT setup: send settings over USB, or join the ProbeHarbor-Setup Wi-Fi network
Easy to mistake for
The update broke saved settings.
Was
Browser flashing writes one merged image at offset 0, which covers the settings partition too.
Fix
Expected behaviour. Send settings again after every browser flash.

What the bench's crash translator says about this log: ProbeHarbor: the probe has no settings. A fresh flash erases them, so send Wi-Fi and the key again.

Exhibit 06

Every time I look, it restarts

ESP32-S3 on its native USB portFrom ProbeHarbor's tests
USB_UART_CHIP_RESET
Easy to mistake for
A crash loop.
Was
Opening the native USB serial port resets the chip. Each new connection from the bench restarts the firmware.
Fix
Nothing to fix. Do not read uptime or a boot counter as evidence of a crash on this port.

What the bench's crash translator says about this log: Reset caused by opening the native USB port. Normal on the ESP32-S3 and C3.

Exhibit 07

Dies the moment Wi-Fi starts

Any ESP32Typical output
Brownout detector was triggered
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
Easy to mistake for
A bug in the Wi-Fi code.
Was
The radio pulls a burst of current at start-up and the 3.3 V rail dips. Long thin USB cables and unpowered hubs are the usual reason.
Fix
Shorter cable, powered hub, or a capacitor of 100 µF or more across 3V3 and GND.

What the bench's crash translator says about this log: The supply voltage dipped below the safe level. Try a shorter USB cable, a powered hub, or a capacitor across 3V3 and GND. Wi-Fi start-up is the usual trigger. SW_CPU_RESET: The firmware restarted itself, either with ESP.restart() or after a crash. Look just above for a panic.

Exhibit 08

Works on the bench, boot loops in the enclosure

Classic ESP32Typical output
rst:0x10 (RTCWDT_RTC_RESET),boot:0x33 (SPI_FAST_FLASH_BOOT)
flash read err, 1000
Easy to mistake for
A corrupted flash chip.
Was
Something wired to GPIO 12 held it high at reset. That pin selects the flash voltage, so the flash chip was run at the wrong one.
Fix
Move the part off GPIO 12, or make sure it cannot pull the pin high during boot.

What the bench's crash translator says about this log: RTCWDT_RTC_RESET: The low-level watchdog reset the chip. Often a boot loop, bad flash contents or unstable power. The bootloader could not read the flash chip. Check the flash mode and size settings, then flash again.

Exhibit 09

Flashed fine, then nothing runs

Any ESP32Typical output
rst:0x1 (POWERON_RESET),boot:0x3 (DOWNLOAD_BOOT(UART0/UART1/SDIO_REI_REO_V2))
waiting for download
Easy to mistake for
The upload did not take.
Was
GPIO 0 was low at reset, so the chip is waiting for firmware instead of running it. A part on GPIO 0 or a stuck BOOT button does this.
Fix
Free GPIO 0, then press EN or RST.

What the bench's crash translator says about this log: POWERON_RESET: Normal start after power-up or the EN button. The board is in download mode, waiting for new firmware. Press EN or RST to run what is already flashed.

Exhibit 10

Crash right after setup

Any ESP32Typical output
Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
Backtrace: 0x400d1a2b:0x3ffb1f10 0x400d2c3d:0x3ffb1f30
Easy to mistake for
Bad hardware.
Was
The code used an object before it was set up, most often a sensor or display whose begin() failed and was not checked.
Fix
Check the return value of begin() and stop with a clear message when it fails.

What the bench's crash translator says about this log: Crash on core 1: LoadProhibited. The code read from an address it may not touch. Usually a null or dangling pointer, or an object used before it was set up. Backtrace: these addresses name the functions that were running. To turn them into file and line numbers you need the firmware's .elf file: addr2line -pfiaC -e firmware.elf 0x400d1a2b 0x400d2c3d

Exhibit 11

Resets every few seconds while waiting

Any ESP32Typical output
E (10321) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (10321) task_wdt:  - IDLE0 (CPU 0)
Easy to mistake for
Unstable power.
Was
A loop that waits for something without ever yielding, such as while (!sensor.ready()) {} with no delay.
Fix
Put delay(1) or yield() inside every wait loop.

What the bench's crash translator says about this log: A task ran too long without yielding. Add a delay() or yield() inside long loops.