Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deep Sleep Considerations #75

Open
GeorgesOatesLarsen opened this issue May 9, 2021 · 6 comments
Open

Deep Sleep Considerations #75

GeorgesOatesLarsen opened this issue May 9, 2021 · 6 comments

Comments

@GeorgesOatesLarsen
Copy link
Contributor

Firstly, there is the silly placement of the ESP32 power LED. This will bleed our power. Remove it. #73

See documentation on sleep modes for ESP32:
https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/sleep_modes.html

We are namely interested in esp32 deep sleep. Wakeup can be triggered by any of the RTC_GPIO pins. It is unclear why these are named after the Real Time Clock, but in general RTC_GPIO are the only pins accessible in deep sleep or deeper.

See:
https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/gpio.html

While I'm at it, here are the big three datasheets from esp32:
https://www.espressif.com/sites/default/files/documentation/esp32_hardware_design_guidelines_en.pdf
https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf
https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf

And for the WROOM:
https://www.espressif.com/sites/default/files/documentation/esp32-wroom-32_datasheet_en.pdf

Somewhere in those four documents lies documentation on what the RTC-GPIO pins actually are.

@GeorgesOatesLarsen
Copy link
Contributor Author

Ah, yes, section 2.2 of the WROOM database. Pin definitions. Anything labeled "RTC_GPIOX", such as "RTC_GPIO0" or "RTC_GPIO1", so forth. Those are our RTC GPIO pins.

@GeorgesOatesLarsen
Copy link
Contributor Author

We are interested in awakening on RAWSENSE. This is IO34, pin 6. Fortunately for us, this is, in fact, an RTC_GPIO. It is RTC_GPIO4.

We are interested in keeping our BAT_EN signal low. Currently, BAT_EN lives on IO21, pin 33. Unfortunately, this is not an RTC GPIO.

We have two options:

  1. Relocate BAT_EN to a GPIO pin that is RTC_GPIO.
  2. Some sources suggest that a special setting can keep the main GPIO active during deep sleep.

Namely:

gpio_hold_en(GPIO_NUM_25);
gpio_deep_sleep_hold_en();

espressif/arduino-esp32#2712

Need to test what the power implications of that second option are. Will test now.

@GeorgesOatesLarsen
Copy link
Contributor Author

The excellent news is that this approach does successfully maintain GPIO_21 in deep sleep mode. Here is a simple test:

void setup() {
  Serial.begin(115200);
  pinMode(GPIO_NUM_21,OUTPUT);
  digitalWrite(GPIO_NUM_21, LOW);
}

void loop() {
  for (int i = 0; i < 5; i++) {
    Serial.println("Going to sleep soon.");
    delay(1000);
  }
  gpio_hold_en((gpio_num_t) 21);
  gpio_deep_sleep_hold_en();
  delay(1000);
  esp_deep_sleep_start();
  Serial.println("This never prints");
}

Changing the digitalWRITE call to HIGH or LOW will cause the pin to maintain its state. Deep sleep is being entered. Second to next step is to manually remove the drainer diode and get some current measurements. But first, lets see if we can awaken from deep sleep.

@GeorgesOatesLarsen
Copy link
Contributor Author

GeorgesOatesLarsen commented May 9, 2021

The ESP-IDF function for wakeup is esp_sleep_enable_ext0_wakeup. We want ext0 since we want only a single pin to wake us up. Documented here:
https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/sleep_modes.html

Yes, wake from sleep functions perfectly:

void setup() {
  Serial.begin(115200);
  Serial.println("BOOT!");
  pinMode(GPIO_NUM_21,OUTPUT);
  digitalWrite(GPIO_NUM_21, LOW);
  esp_sleep_enable_ext0_wakeup((gpio_num_t) 34, HIGH);
}

void loop() {
  for (int i = 0; i < 5; i++) {
    Serial.println("Going to sleep soon.");
    delay(1000);
  }
  gpio_hold_en((gpio_num_t) 21);
  gpio_deep_sleep_hold_en();
  delay(1000);
  esp_deep_sleep_start();
  Serial.println("This never prints, since deep sleep resets memory.");
}
BOOT!
Going to sleep soon.
Going to sleep soon.
Going to sleep soon.
Going to sleep soon.
Going to sleep soon.
ets Jun  8 2016 00:22:57

rst:0x5 (DEEPSLEEP_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:10044
load:0x40080400,len:5900
entry 0x400806ac
BOOT!

@GeorgesOatesLarsen
Copy link
Contributor Author

Now I just need to characterize the power draw. I don't have very sensitive current measuring capabilities, but I'll do my best. I will deliver batteries to the battery pins, passed through voltmeter.

Yeeeeaaah, my multimeter can't even measure the current when in deep sleep mode. It's like, on the order of less than a microamp. I am pretty sure a full charge will last years with this current consumption,

@GeorgesOatesLarsen
Copy link
Contributor Author

Just as a final summary:

Near start-up, call:

  esp_sleep_enable_ext0_wakeup((gpio_num_t) 34, HIGH);

to enable wakeup triggered by rising engine power.

To go into deep sleep:
Bring GPIO21 to LOW (this disables use of the battery)

Then, call:

gpio_hold_en((gpio_num_t) 21);
gpio_deep_sleep_hold_en();```

Then wait a few hundred milliseconds for good measure.

Then, call:
```C
esp_deep_sleep_start();```

And as of that moment, the ESP32 will enter deep sleep.

Please note that deep sleep totally wipes ESP32 memory, so no variable values or anything of that sort will be retained after waking up. Waking up from deep sleep will be akin to experiencing a reset. So, if there is anything nontransient you want to return after deep sleep, you'll need to use the onboard flash to save it.




Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant