Using both timer and external signal for esp32 deep sleep

Hello, I am working on a project for school in which we need our adafruit esp32 featherwing to use two different wakeup reasons from the deepsleep function to save energy. The esp32 is hooked up to a solar charger and everytime the charger sends a charge the esp32 wakes up from the external signal and adds +1 to a counter. Furthermore the esp32 is supposed to wake up every 15 minutes to send the mentioned countervalue to adafruit IO. The problem is that we do not know how to use both functions without them triggering eachother. At the moment we just have the external signal working as you can see in the code below:

/*
Deep Sleep with External Wake Up
=====================================
This code displays how to use deep sleep with
an external trigger as a wake up source and how
to store data in RTC memory to use it over reboots

This code is under Public Domain License.

Hardware Connections
======================
Push Button to GPIO 33 pulled down with a 10K Ohm
resistor

NOTE:
======
Only RTC IO can be used as a source for external wake
source. They are pins: 0,2,4,12-15,25-27,32-39.

Author:
Pranav Cherukupalli <cherukupallip@gmail.com>
*/

#define BUTTON_PIN_BITMASK 0x200000000 // 2^33 in hex
char reason;

RTC_DATA_ATTR int bootCount = 0;

/*
Method to print the reason by which ESP32
has been awaken from sleep
*/
void print_wakeup_reason(){
  esp_sleep_wakeup_cause_t wakeup_reason;

  wakeup_reason = esp_sleep_get_wakeup_cause();

  switch(wakeup_reason)
  {
    case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
    case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
    case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
    case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
    case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
    default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
  }
}

void setup(){
  pinMode(33,INPUT_PULLUP);
  Serial.begin(115200);
   //Increment boot number and print it every reboot
   ++bootCount;
   Serial.println("Boot number: " + String(bootCount));

  //Print the wakeup reason for ESP32
   print_wakeup_reason();
    

  /*
  First we configure the wake up source
  We set our ESP32 to wake up for an external trigger.
  There are two types for ESP32, ext0 and ext1 .
  ext0 uses RTC_IO to wakeup thus requires RTC peripherals
  to be on while ext1 uses RTC Controller so doesnt need
  peripherals to be powered on.
  Note that using internal pullups/pulldowns also requires
  RTC peripherals to be turned on.
  */
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_33,0); //1 = High, 0 = Low

  //If you were to use ext1, you would use it like
  //esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK,ESP_EXT1_WAKEUP_ANY_HIGH);

  //Go to sleep now
  Serial.println("Going to sleep now");
  esp_deep_sleep_start();
  Serial.println("This will never be printed");
}

void loop(){
  //This is not going to be called
}

How do I implement a timer wakeup to upload the bootCount to adafruit IO without it triggering what is in the setup and vice versa. Thank you for your help! :slight_smile:

Your post is breaking forum rules. Please read the guide in the sticky post, then modify your post above and add the code tags.

Sorry, I believe I have edited the post to abide the rules now.

Thanks, +1 karma.

Can you read the pin just after setting it to INPUT_PULLUP, and use that to decide what action to take?

Yes, the pin receives the signal and adds 1 to the bootCount which we can see in the serial monitor.

Sorry if i misunderstand anything. I am quite new to arduino.

Could you point out the code RTC GPIO is configured?

You might want to take a look at the ESP32 API for more RTC configuration info.

In this case you might want to use the ULP processor. Yes, the ESP32 has 2 processors. The ULP is well suited to handle the RTC thingies. You can use, in the Arduino IDE, the GNU legacy method of programming the ULP. Under the Arduino IDE, the ULP processor only has 2K of RTC_SLOW and RTC_FAST ram, not 8K as in the ESP32 IDE documentation, and is address in 32 bit words. I use address spaces 2001 to 2048 for variable assignments. I use address 0000 to 2000 for program storage.

Code for the ULP is written in MACRO Assembler.


From your description of what you are trying to do, the ESP32 Arduino core will not be up the task over using the ESP32 API.

Thank you :slight_smile:
I will look into this.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.