Symptom
The sketch works until a button or sensor fires its interrupt, then the ESP32 resets with Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1). A bouncing button makes it worse: the handler runs many times in quick succession.
Cause
An interrupt handler blocks the core it runs on. Serial.println(), delay(), I2C/SPI transactions, Wi-Fi or file-system calls are far too slow for that context, so the interrupt watchdog decides the system is stuck and resets it. The Arduino reference also notes that inside a handler delay() doesn't work, millis() doesn't advance and incoming serial data can be lost.
Fix: flag in the ISR, work outside
volatile bool buttonPressed = false;
void ARDUINO_ISR_ATTR onButton() { // attribute as used in the official arduino-esp32 examples
buttonPressed = true; // nothing else
}
void setup() {
Serial.begin(115200);
pinMode(BUTTON_PIN, INPUT_PULLUP);
attachInterrupt(BUTTON_PIN, onButton, FALLING);
}
void loop() {
if (buttonPressed) {
buttonPressed = false;
Serial.println("pressed"); // slow work happens here
}
}
- Declare every variable shared with the ISR
volatile. - Debounce in
loop()(ignore further events for, say, 50 ms), or debounce in hardware. - In ESP-IDF or FreeRTOS code, notify a task from the ISR (
FromISRAPI variants) instead of polling a flag. - If the ISR must count events quickly, increment a counter only; read and reset it outside the ISR with interrupts briefly disabled or with an atomic operation.
Sources: Stack Exchange (CC BY-SA 4.0) — see links.