17
17
18
18
ESP32 Lambda FunctionalInterrupt Example
19
19
========================================
20
-
20
+
21
21
This example demonstrates how to use lambda functions with FunctionalInterrupt
22
22
for GPIO pin interrupt callbacks on ESP32. It shows CHANGE mode detection
23
23
with LED toggle functionality and proper debouncing.
31
31
2. LED toggle on button press (FALLING edge)
32
32
3. Edge type detection using digitalRead() within ISR
33
33
4. Hardware debouncing with configurable timeout
34
-
34
+
35
35
IMPORTANT NOTE ABOUT ESP32 INTERRUPT BEHAVIOR:
36
36
- Only ONE interrupt handler can be attached per GPIO pin at a time
37
37
- Calling attachInterrupt() on a pin that already has an interrupt will override the previous one
44
44
#include < FunctionalInterrupt.h>
45
45
46
46
// Pin definitions
47
- #define BUTTON_PIN BOOT_PIN // BOOT BUTTON - change as needed
47
+ #define BUTTON_PIN BOOT_PIN // BOOT BUTTON - change as needed
48
48
#ifdef LED_BUILTIN
49
- #define LED_PIN LED_BUILTIN
49
+ #define LED_PIN LED_BUILTIN
50
50
#else
51
51
#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
53
53
#endif
54
54
55
55
// Global variables for interrupt handling (volatile for ISR safety)
@@ -58,7 +58,7 @@ volatile uint32_t buttonReleaseCount = 0;
58
58
volatile bool buttonPressed = false ;
59
59
volatile bool buttonReleased = false ;
60
60
volatile 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
62
62
63
63
// Debouncing variables (volatile for ISR safety)
64
64
volatile unsigned long lastButtonInterruptTime = 0 ;
@@ -72,15 +72,15 @@ IRAM_ATTR std::function<void()> changeModeLambda = []() {
72
72
// Simple debouncing: check if enough time has passed since last interrupt
73
73
unsigned long currentTime = millis ();
74
74
if (currentTime - lastButtonInterruptTime < DEBOUNCE_DELAY_MS) {
75
- return ; // Ignore this interrupt due to bouncing
75
+ return ; // Ignore this interrupt due to bouncing
76
76
}
77
77
78
78
// Read current pin state to determine edge type
79
79
bool currentState = digitalRead (BUTTON_PIN);
80
80
81
81
// State-based debouncing: only process if state actually changed
82
82
if (currentState == lastButtonState) {
83
- return ; // No real state change, ignore (hysteresis/noise)
83
+ return ; // No real state change, ignore (hysteresis/noise)
84
84
}
85
85
86
86
// Update timing and state
@@ -105,7 +105,7 @@ IRAM_ATTR std::function<void()> changeModeLambda = []() {
105
105
106
106
void setup () {
107
107
Serial.begin (115200 );
108
- delay (1000 ); // Allow serial monitor to connect
108
+ delay (1000 ); // Allow serial monitor to connect
109
109
110
110
Serial.println (" ESP32 Lambda FunctionalInterrupt Example" );
111
111
Serial.println (" ========================================" );
@@ -144,15 +144,13 @@ void loop() {
144
144
// Check for button presses
145
145
if (buttonPressed) {
146
146
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" );
149
148
}
150
149
151
150
// Check for button releases
152
151
if (buttonReleased) {
153
152
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);
156
154
}
157
155
158
156
delay (10 );
0 commit comments