How to lower the power consumption of this ESP32 during delay(500)?

The following code works. It does the following:

  • wake up when pin GPIO0 is connected to GND (the pulse duration is 400 milliseconds)
  • once every 10 wakings, I send the current index to a server with a HTTP request over WiFi
  • then go to deep sleep

Since GPIO0 is connected to GND during 400 milliseconds, it can reboot multiple times during these 400 milliseconds, which I don't want. So I added delay(500); at the end of the code.

Problem: this delay(500); is probably a waste of power, since the ESP32 is battery powered. site

Question: by what could I replace this delay(500) to avoid that the ESP32 reboots multiple times while pin 0 is connected to GND during 400 milliseconds, , with the least power consumption possible?

#include "WiFi.h"
#include "HTTPClient.h"
#include "esp_sleep.h"
byte WIFI_BSSID[] =         {0x01, 0x23, 0x45, 0x67, 0x89, 0x00};
String URL =                "http://example.com/submit?bootcount=";
RTC_DATA_ATTR int bootcount = 0;
HTTPClient http;
void setup() {
    bootcount++;  
    pinMode(0, INPUT_PULLUP);
    esp_sleep_enable_ext0_wakeup(GPIO_NUM_0, 0);
    if (bootcount % 10 == 0) {
        WiFi.begin("MySSID", "password", 0, WIFI_BSSID);
        while (WiFi.status() != WL_CONNECTED) {
            delay(20); 
        }
        URL += bootcount;
        http.begin(URL.c_str());
        http.GET();
        http.end();
    }
    delay(500);
    esp_deep_sleep_start();
}
void loop() {
}

deep sleep with wakeup-source time going to deepsleep for 500 milliseconds

does it have to be GPIO 0or would another GPIO be possible too?

CMOS-monoflop with deadtime 600 milliseconds create a single short pulse for a single boot.

bistable relay that disconnects signal from GPIO 0 as soon as it has booted
and reconnects just before next deep_sleep

Some kind of a tristate-buffer that is switched to HIGH impedance right after booting and switched back right before deep_sleep

Can someone explain how bootcount ever gets to 10? It looks like it is initialized to zero on every wakeup. What am I missing?

Anyway, how about inserting a small capacitor in the wakeup line to shorten the low pulse period?

The ESP32 has 2 processors. The one your code is currently running on has 2 cores. The other processor is known as the ULP a FSM processor. The ULP can run when the main processor is sleeping. The ULP has 2 RAM storage locations, RTC_FAST and RTC_SLOW. RTC_FAST memory can retain its contents during deep sleeps.

The wakeup from deep sleep is not a complete reboot of the CPU. The OS of the ESP32 is able to understand that the RTC ram was allocated once and to not allocate it again upon deep sleep wakeup.

I'd replace delay with a wake up time for deep sleep.

In the following task deep sleep is set for a wake up time of one minute. In essence a one minute delay.

void fSleepyTime( void *pvParmeters )
{
  for (;;)
  {
    xEventGroupWaitBits (eg, evtSleepyTime, pdTRUE, pdTRUE, portMAX_DELAY );
    xSemaphoreTake( sema_MQTT_KeepAlive, portMAX_DELAY );
    MQTTclient.disconnect();
    WiFi.disconnect();
    esp_sleep_enable_timer_wakeup( 60000000 ); // set timer to wake up once a minute 60000000uS
    esp_deep_sleep_start();
  }
  vTaskDelete( NULL );
} //void fSleepyTime( void *pvParmeters )

RNT says GPIO 0 is creating a PWM-signal on boot. It might be if you use GPIO 0 as the wake up-reason that this interfere with the PWM-signal but I haven't measured if the ESP32 awakes from deep-sleep if the PWM-signal occurs.

roll back to a working version of going to deep_sleep with an incrementing bootcounter
and then do

  • small modification test again minimum TWO wakeups
  • small modification test again minimum TWO wakeups
    ...

code

#define uS_TO_S_FACTOR 1000000  /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP  20        /* Time ESP32 will go to sleep (in seconds) */

RTC_DATA_ATTR int bootCount = 0;

// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &startOfPeriod, unsigned long TimePeriod) {
  unsigned long currentMillis  = millis();
  if ( currentMillis - startOfPeriod >= TimePeriod ) {
    // more time than TimePeriod has elapsed since last time if-condition was true
    startOfPeriod = currentMillis; // a new period starts right here so set new starttime
    return true;
  }
  else return false;            // actual TimePeriod is NOT yet over
}

unsigned long MyTestTimer = 0;                   // Timer-variables MUST be of type unsigned long
const byte    OnBoard_LED = 2;


void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {
  static unsigned long MyBlinkTimer;
  pinMode(IO_Pin, OUTPUT);
  if ( TimePeriodIsOver(MyBlinkTimer, BlinkPeriod) ) {
    digitalWrite(IO_Pin, !digitalRead(IO_Pin) );
  }
}

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() {
  Serial.begin(115200);
  Serial.println();
  //delay(1000); //Take some time to open up the Serial Monitor
  //Increment boot number and print it every reboot
  bootCount++;
  Serial.println("Boot number: " + String(bootCount));
  //Print the wakeup reason for ESP32
  print_wakeup_reason();
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
  Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) +  " Seconds");
  Serial.println("Going to sleep in 10 seconds");
  //digitalWrite(LED_Pin,HIGH);
}

void loop() {
  BlinkHeartBeatLED(OnBoard_LED, 100);
  
  if ( TimePeriodIsOver(MyTestTimer, 10000) ) {
    esp_deep_sleep_start();
    Serial.println("This will never be printed");
  }
}

serial output

21:24:38.049 -> ets Jun  8 2016 00:22:57
21:24:38.049 -> 
21:24:38.049 -> rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
21:24:38.084 -> configsip: 0, SPIWP:0xee
21:24:38.084 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
21:24:38.084 -> mode:DIO, clock div:1
21:24:38.084 -> load:0x3fff0030,len:1344
21:24:38.084 -> load:0x40078000,len:13864
21:24:38.084 -> load:0x40080400,len:3608
21:24:38.084 -> entry 0x400805f0
21:24:38.224 -> 
21:24:38.224 -> Boot number: 1
21:24:38.224 -> Wakeup was not caused by deep sleep: 0
21:24:38.224 -> Setup ESP32 to sleep for every 20 Seconds
21:24:38.224 -> Going to sleep in 10 seconds
21:25:08.066 -> ets Jun  8 2016 00:22:57
21:25:08.066 -> 
21:25:08.066 -> rst:0x5 (DEEPSLEEP_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
21:25:08.066 -> configsip: 0, SPIWP:0xee
21:25:08.066 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
21:25:08.066 -> mode:DIO, clock div:1
21:25:08.066 -> load:0x3fff0030,len:1344
21:25:08.066 -> load:0x40078000,len:13864
21:25:08.066 -> load:0x40080400,len:3608
21:25:08.066 -> entry 0x400805f0
21:25:08.136 -> 
21:25:08.136 -> Boot number: 2
21:25:08.136 -> Wakeup caused by timer
21:25:08.136 -> Setup ESP32 to sleep for every 20 Seconds
21:25:08.136 -> Going to sleep in 10 seconds
21:25:37.985 -> ets Jun  8 2016 00:22:57
21:25:37.985 -> 
21:25:37.985 -> rst:0x5 (DEEPSLEEP_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
21:25:37.985 -> configsip: 0, SPIWP:0xee
21:25:37.985 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
21:25:37.985 -> mode:DIO, clock div:1
21:25:37.985 -> load:0x3fff0030,len:1344
21:25:37.985 -> load:0x40078000,len:13864
21:25:38.020 -> load:0x40080400,len:3608
21:25:38.020 -> entry 0x400805f0
21:25:38.055 -> 
21:25:38.055 -> Boot number: 3
21:25:38.055 -> Wakeup caused by timer
21:25:38.055 -> Setup ESP32 to sleep for every 20 Seconds
21:25:38.055 -> Going to sleep in 10 seconds
21:26:07.918 -> ets Jun  8 2016 00:22:57
21:26:07.918 -> 
21:26:07.918 -> rst:0x5 (DEEPSLEEP_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
21:26:07.918 -> configsip: 0, SPIWP:0xee
21:26:07.918 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
21:26:07.952 -> mode:DIO, clock div:1
21:26:07.952 -> load:0x3fff0030,len:1344
21:26:07.952 -> load:0x40078000,len:13864
21:26:07.952 -> load:0x40080400,len:3608
21:26:07.952 -> entry 0x400805f0
21:26:07.987 -> 
21:26:07.987 -> Boot number: 4
21:26:07.987 -> Wakeup caused by timer
21:26:07.987 -> Setup ESP32 to sleep for every 20 Seconds
21:26:07.987 -> Going to sleep in 10 seconds

best regards Stefan

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