ESP32-C3 Light Sleep Timing
Posted: Mon Jan 16, 2023 4:11 am
I was interested in how long it takes an ESP32-C3 to enter and wake from light-Sleep, but I could not find anything posted, so i did some experimentation. I thought I would post the results here for others.
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.
I then fed a square wave around 100 Hz into GPIO 4, and watched GPIO 13 to see when the ESP entered and exited sleep mode.
My notes from taking a bunch of measurements are:
So the bottom line is that it takes about 320 us to enter Light Sleep mode and then about 500 us to return to normal execution. there is about 10-20us of jitter in the signals.
Here are a few lines from the Serial console:
I'll post some scope images in my next post in a few minutes.
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.