1717
1818 ESP32 Lambda FunctionalInterrupt Example
1919 ========================================
20-
20+
2121 This example demonstrates how to use lambda functions with FunctionalInterrupt
2222 for GPIO pin interrupt callbacks on ESP32. It shows CHANGE mode detection
2323 with LED toggle functionality and proper debouncing.
3131 2. LED toggle on button press (FALLING edge)
3232 3. Edge type detection using digitalRead() within ISR
3333 4. Hardware debouncing with configurable timeout
34-
34+
3535 IMPORTANT NOTE ABOUT ESP32 INTERRUPT BEHAVIOR:
3636 - Only ONE interrupt handler can be attached per GPIO pin at a time
3737 - Calling attachInterrupt() on a pin that already has an interrupt will override the previous one
4444#include < FunctionalInterrupt.h>
4545
4646// Pin definitions
47- #define BUTTON_PIN BOOT_PIN // BOOT BUTTON - change as needed
47+ #define BUTTON_PIN BOOT_PIN // BOOT BUTTON - change as needed
4848#ifdef LED_BUILTIN
49- #define LED_PIN LED_BUILTIN
49+ #define LED_PIN LED_BUILTIN
5050#else
5151#warning Using LED_PIN = GPIO 2 as default - change as needed
52- #define LED_PIN 2 // change as needed
52+ #define LED_PIN 2 // change as needed
5353#endif
5454
5555// Global variables for interrupt handling (volatile for ISR safety)
@@ -58,7 +58,7 @@ volatile uint32_t buttonReleaseCount = 0;
5858volatile bool buttonPressed = false ;
5959volatile bool buttonReleased = false ;
6060volatile bool ledState = false ;
61- volatile bool ledStateChanged = false ; // Flag to indicate LED needs updating
61+ volatile bool ledStateChanged = false ; // Flag to indicate LED needs updating
6262
6363// Debouncing variables (volatile for ISR safety)
6464volatile unsigned long lastButtonInterruptTime = 0 ;
@@ -72,15 +72,15 @@ IRAM_ATTR std::function<void()> changeModeLambda = []() {
7272 // Simple debouncing: check if enough time has passed since last interrupt
7373 unsigned long currentTime = millis ();
7474 if (currentTime - lastButtonInterruptTime < DEBOUNCE_DELAY_MS) {
75- return ; // Ignore this interrupt due to bouncing
75+ return ; // Ignore this interrupt due to bouncing
7676 }
7777
7878 // Read current pin state to determine edge type
7979 bool currentState = digitalRead (BUTTON_PIN);
8080
8181 // State-based debouncing: only process if state actually changed
8282 if (currentState == lastButtonState) {
83- return ; // No real state change, ignore (hysteresis/noise)
83+ return ; // No real state change, ignore (hysteresis/noise)
8484 }
8585
8686 // Update timing and state
@@ -105,7 +105,7 @@ IRAM_ATTR std::function<void()> changeModeLambda = []() {
105105
106106void setup () {
107107 Serial.begin (115200 );
108- delay (1000 ); // Allow serial monitor to connect
108+ delay (1000 ); // Allow serial monitor to connect
109109
110110 Serial.println (" ESP32 Lambda FunctionalInterrupt Example" );
111111 Serial.println (" ========================================" );
@@ -144,15 +144,13 @@ void loop() {
144144 // Check for button presses
145145 if (buttonPressed) {
146146 buttonPressed = false ;
147- Serial.printf (" ==> Button PRESSED! Count: %lu, LED: %s (FALLING edge)\r\n " ,
148- buttonPressCount, ledState ? " ON" : " OFF" );
147+ Serial.printf (" ==> Button PRESSED! Count: %lu, LED: %s (FALLING edge)\r\n " , buttonPressCount, ledState ? " ON" : " OFF" );
149148 }
150149
151150 // Check for button releases
152151 if (buttonReleased) {
153152 buttonReleased = false ;
154- Serial.printf (" ==> Button RELEASED! Count: %lu (RISING edge)\r\n " ,
155- buttonReleaseCount);
153+ Serial.printf (" ==> Button RELEASED! Count: %lu (RISING edge)\r\n " , buttonReleaseCount);
156154 }
157155
158156 delay (10 );
0 commit comments