I wrote some code to go into a loop entering Light-Sleep and then wake up on a GPIO (4) going high. I also set another GPIO (13) during the process so I could look at the timing on my scope.
Here is the basic loop. It uses the Arduino environment along with some IDF API calls on an ESP32-C3 development board running at 160 MHz.
Code: Select all
// Go into an infinite loop of Light-Sleeps waiting on a GPIO to wake us up.
// - GPIO04 - Wake-up Pin - Feed 100 Hz (3.3V) into this
// - This is level based, so it will wake up as long as it is high.
// - If it is already high, we will wake up right away.
// - GPIO13 - Sleep-Indicator pin
uint32_t CpuCountS; // Count of CPU cycles
uint32_t CpuCountE;
uint64_t MicrosS; // From ESP microseconds timer
uint64_t MicrosE;
pinMode(GPIO_NUM_4, INPUT);
pinMode(GPIO_NUM_13, OUTPUT);
gpio_wakeup_enable(GPIO_NUM_4, GPIO_INTR_HIGH_LEVEL); // Enable wakeup on high-level on GPIO 4
esp_sleep_enable_gpio_wakeup(); // Enable wake-up via GPIO pin level
// Infinite loop
for (uint16_t i; ; i++) {
while (digitalRead(GPIO_NUM_4) == HIGH) {} // Loop until the pin is low since we don't want to wake up right away
MicrosS = esp_timer_get_time();
CpuCountS = cpu_hal_get_cycle_count();
GPIO.out_w1ts.out_w1ts = (1 << GPIO_NUM_13); // Extra-fast - Set HIGH
esp_light_sleep_start();
GPIO.out_w1tc.out_w1tc = (1 << GPIO_NUM_13); // Extra-fast - Set LOW
CpuCountE = cpu_hal_get_cycle_count();
MicrosE = esp_timer_get_time();
printf("Sleep wake-up via GPIO after: %10.6f secs clock. %10.6f secs CPU.\n",
(MicrosE - MicrosS)/1000000.0, (CpuCountE - CpuCountS)/(1000000.0 * 160));
}
// Cleanup wakeup settings even though this will never be executed in this code.
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_GPIO);
gpio_wakeup_disable(GPIO_NUM_4);
My notes from taking a bunch of measurements are:
Code: Select all
Light Sleep Timing Data
- Going to sleep:
+ 0 us - GPIO13 goes high - Just before the Sleep call.
+320 us - GPIO 13 goes Hi-z
- Voltage drops to Vcc/2 in a couple of us.
- Drops to zero in < 5us when pulled low by 20K ohms
+600 us - Drops to zero loaded with a 1x scope probe.
+900 us - Drops to zero loaded with a 10x scope probe.
- Basically, sleep is entered about 320 us after the esp_light_sleep_start() call.
- Waking up:
+ 0 us - GPIO 4 goes high to wake up the ESP32
+280-290 us - GPIO 13 goes high again as pin returns to output-high from hi-z sleep mode
+490-500 us - GPIO 13 goes low, set by code immediately after sleep returns.
- The time returned by esp_timer_get_time() pretty accurately measures the true elapsed time
including the sleep period.
- The time returned by cpu_hal_get_cycle_count() is always about 250 us over the sleep period
regardless of the sleep length.
- That seems to be how long the CPU actually executes during the sleep entry and exit.
Here are a few lines from the Serial console:
Code: Select all
Sleep wake-up via GPIO after: 0.000989 secs clock. 0.000244 secs CPU.
Sleep wake-up via GPIO after: 0.001002 secs clock. 0.000243 secs CPU.
Sleep wake-up via GPIO after: 0.000995 secs clock. 0.000249 secs CPU.
Sleep wake-up via GPIO after: 0.001001 secs clock. 0.000250 secs CPU.
Sleep wake-up via GPIO after: 0.000992 secs clock. 0.000250 secs CPU.
Sleep wake-up via GPIO after: 0.001000 secs clock. 0.000250 secs CPU.
Sleep wake-up via GPIO after: 0.000994 secs clock. 0.000245 secs CPU.
Sleep wake-up via GPIO after: 0.000993 secs clock. 0.000245 secs CPU.
Sleep wake-up via GPIO after: 0.001002 secs clock. 0.000243 secs CPU.
Sleep wake-up via GPIO after: 0.001003 secs clock. 0.000249 secs CPU.
Sleep wake-up via GPIO after: 0.001000 secs clock. 0.000251 secs CPU.
Sleep wake-up via GPIO after: 0.000993 secs clock. 0.000251 secs CPU.
Sleep wake-up via GPIO after: 0.001001 secs clock. 0.000250 secs CPU.
Sleep wake-up via GPIO after: 0.000989 secs clock. 0.000244 secs CPU.
Sleep wake-up via GPIO after: 0.000995 secs clock. 0.000245 secs CPU.
Sleep wake-up via GPIO after: 0.001002 secs clock. 0.000244 secs CPU.
Sleep wake-up via GPIO after: 0.000995 secs clock. 0.000244 secs CPU.