ESP32-C6 deep_sleep and external wakeup + interrupt
Posted: Sun Feb 18, 2024 2:54 pm
Hello,
I've a lot of experience with programming and computers, but I'm pretty new to microcontrollers and making electronics.
For a PIR project (substituting my current alarm's PIR's controller with new ones as the current controllers aren't supported any more), I've a little prototype with an ESP32-C6-WROOM-1 dev board connected on a breadboard in the following way:
- 3v pin to +
- GRD pin to -
- pin 4 pulled down with resistor to -
- a floating wire connected to pin 4 for testing
This is the behavior I need:
- ESP32 is turned on
- ESP32 goes to sleep
- pin 4 goes to high (testing wire touching +)
- ESP32 wakes up (cause: external signal)
- pirInterrupt() is called
- "Motion detected!" is printed
- ESP32 goes to sleep
To achieve this I wrote the following code:
When I touch + with the testing wire I get this:
As you can see
- the wakeup is caused by "Timer"
- pirInterrupt() is not called
- "Motion detected!" is not printed
While debugging I noticed that if I quickly touch the + rail multiple times pirInterrupt() is called and "Motion detected!" is printed, I have one only possible explanation for this: Wakeup "consumes" the signal so the interrupt needs a new signal to work.
My questions are:
1) Why is the wake-up caused by "Timer"? I was expecting one of the 2 "Wakeup caused by external signal using [...]", what am I doing wrong? (I will need to do different things depending on the wakeup cause)
2) What's the best way to solve the signal issue? Since I cannot control the signal's producer, I thought I could put a small capacitor in to "buffer" the signal and perhaps allow it to be "consumed" twice, but I'm afraid the cap might also add a "debounce" effect and possibly mask series of signals or cause other bugs further into the project.
I've a lot of experience with programming and computers, but I'm pretty new to microcontrollers and making electronics.
For a PIR project (substituting my current alarm's PIR's controller with new ones as the current controllers aren't supported any more), I've a little prototype with an ESP32-C6-WROOM-1 dev board connected on a breadboard in the following way:
- 3v pin to +
- GRD pin to -
- pin 4 pulled down with resistor to -
- a floating wire connected to pin 4 for testing
This is the behavior I need:
- ESP32 is turned on
- ESP32 goes to sleep
- pin 4 goes to high (testing wire touching +)
- ESP32 wakes up (cause: external signal)
- pirInterrupt() is called
- "Motion detected!" is printed
- ESP32 goes to sleep
To achieve this I wrote the following code:
- #include <esp_sleep.h>
- #define PIR_PIN 4 // GPIO pin connected to the PIR sensor
- #define RTC_PIN GPIO_NUM_4 // RTC_IO pin corresponding to the GPIO pin connected to the PIR sensor
- RTC_DATA_ATTR volatile bool pirDetected = false;
- void RTC_IRAM_ATTR pirInterrupt() {
- pirDetected = true;
- }
- void printWakeupReason() {
- esp_sleep_wakeup_cause_t wakeup_reason = esp_sleep_get_wakeup_cause();
- switch(wakeup_reason) {
- case 1 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
- case 2 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
- case 3 : Serial.println("Wakeup caused by timer"); break;
- case 4 : Serial.println("Wakeup caused by touchpad"); break;
- case 5 : Serial.println("Wakeup caused by ULP program"); break;
- default : Serial.println("Wakeup was not caused by deep sleep"); break;
- }
- }
- void setup() {
- Serial.begin(115200);
- printWakeupReason();
- pinMode(PIR_PIN, INPUT_PULLDOWN);
- attachInterrupt(digitalPinToInterrupt(PIR_PIN), pirInterrupt, RISING);
- esp_sleep_enable_ext1_wakeup(RTC_PIN, ESP_EXT1_WAKEUP_ANY_HIGH);
- Serial.println("Setup completed.");
- if (pirDetected) {
- pirDetected = false;
- Serial.println("Motion detected!");
- }
- // Enter deep sleep
- Serial.println("Entering deep sleep mode...");
- esp_deep_sleep_start();
- }
- void loop() {
- // Empty loop
- }
Code: Select all
ESP-ROM:esp32c6-20220919
Build:Sep 19 2022
rst:0x5 (SLEEP_WAKEUP),boot:0xc (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:2
load:0x4086c410,len:0xc24
load:0x4086e610,len:0x2708
load:0x40875728,len:0x594
entry 0x4086c410
Wakeup caused by timer
Setup completed.
Entering deep sleep mode...
- the wakeup is caused by "Timer"
- pirInterrupt() is not called
- "Motion detected!" is not printed
While debugging I noticed that if I quickly touch the + rail multiple times pirInterrupt() is called and "Motion detected!" is printed, I have one only possible explanation for this: Wakeup "consumes" the signal so the interrupt needs a new signal to work.
My questions are:
1) Why is the wake-up caused by "Timer"? I was expecting one of the 2 "Wakeup caused by external signal using [...]", what am I doing wrong? (I will need to do different things depending on the wakeup cause)
2) What's the best way to solve the signal issue? Since I cannot control the signal's producer, I thought I could put a small capacitor in to "buffer" the signal and perhaps allow it to be "consumed" twice, but I'm afraid the cap might also add a "debounce" effect and possibly mask series of signals or cause other bugs further into the project.