Skip to content

Commit c2af5fd

Browse files
committed
feat(esp32): add GPIO interrupts with automatic LightSleep enabled
1 parent 1518743 commit c2af5fd

File tree

2 files changed

+86
-1
lines changed

2 files changed

+86
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
Gpio Interrupts with sleep mode
3+
=====================================
4+
This code displays how to use automatic light sleep with a GPIO interrupts.
5+
6+
With a light sleep mode the only available interrupts are ONLOW_WE and ONHIGH_WE.
7+
RISING/FALLING/CHANGE/ONLOW/ONHIGH would be not fired.
8+
Keep in mind that the interrupt ONLOW_WE/ONLOW would be fired repetitively as long as
9+
the input is held in a LOW state, so a single button press by a fraction of second can
10+
easily trigger your interrupt handler a few hundreds times.
11+
The same is valid for ONHIGH_WE/ONHIGH and HIGH level.
12+
To catch every button press only once - we are going to change the interrupt level
13+
(from ONHIGH_WE to ONLOW_WE and vice versa).
14+
Since ONHIGH_WE interrupt handler is detached right on the first execution - it can be
15+
also treated as a RISING interrupt handler.
16+
The same way ONLOW_WE can be treated as a FALLING interrupt handler.
17+
If CHANGE interrupt is needed - just put your logic in both ONHIGH_WE and ONLOW_WE handlers.
18+
19+
This code is under Public Domain License.
20+
21+
Hardware Connections
22+
======================
23+
A button from IO10 to ground (or a jumper wire to mimic that button).
24+
Optionally - an ammeter/scope connected in series with a CPU/DevKit board to measure power consumption.
25+
26+
Author:
27+
Taras Shcherban <[email protected]>
28+
*/
29+
30+
#include "Arduino.h"
31+
#include <atomic>
32+
33+
std::atomic_int interruptsCounter = 0;
34+
35+
#define BTN_INPUT 10
36+
37+
void lowIsrHandler();
38+
39+
void IRAM_ATTR highIsrHandler()
40+
{
41+
// button was released - attach button press interrupt back
42+
attachInterrupt(BTN_INPUT, lowIsrHandler, ONLOW_WE);
43+
}
44+
45+
void IRAM_ATTR lowIsrHandler()
46+
{
47+
// button is pressed - count it
48+
interruptsCounter++;
49+
50+
// attach interrupt to catch an event of button releasing
51+
// implicitly detaches previous interrupt and stops this function from being called
52+
// while the input is held in a LOW state
53+
attachInterrupt(BTN_INPUT, highIsrHandler, ONHIGH_WE);
54+
}
55+
56+
void setup()
57+
{
58+
Serial.begin(115200);
59+
while (!Serial)
60+
; // wait for serial port to connect
61+
62+
// CPU will automatically go into light sleep if no ongoing activity (active task, peripheral activity etc.)
63+
setAutomaticLightSleep(true);
64+
65+
pinMode(BTN_INPUT, INPUT_PULLUP);
66+
attachInterrupt(BTN_INPUT, lowIsrHandler, ONLOW_WE);
67+
68+
// this function is required for GPIO to be able to wakeup CPU from a lightSleep mode
69+
esp_sleep_enable_gpio_wakeup();
70+
}
71+
72+
void loop()
73+
{
74+
Serial.printf("Button press count: %d\n", (int)interruptsCounter);
75+
76+
// Serial output is being suspended during sleeping, so without a Flush call logs
77+
// will be printed to the terminal with a delay depending on how much CPU spends in a sleep state
78+
Serial.flush();
79+
80+
// This is a sleep-aware waiting using delay(). Blocking in this manner
81+
// allows CPU to go into light sleep mode until there is some task to do.
82+
// if you remove that delay completely - CPU will have to call loop() function constantly,
83+
// so no power saving will be available
84+
delay(5000);
85+
}

libraries/ESP32/examples/PowerSave/WiFiModemSleep/WiFiModemSleep.ino

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Cpu automatic LightSleep
2+
WiFi automatic LightSleep
33
=====================================
44
This code displays how to use automatic light sleep with an active WiFi connection
55
and tune WiFi modem sleep modes

0 commit comments

Comments
 (0)