ESP32 Light sleep and time accuracy
Posted: Fri Jan 20, 2023 12:48 pm
I am trying to make power saving for my ESP32 smart watch based on ESP32 - Lillygo TTGo 1.54 e-ink. The idea is that it shows the time, then goes to light sleep for almost a minute, gets back from sleep and draws new time. The problem is the time accuracy - for some reason when I am using this approach (without light sleep no issues with time btw) the time shifts forwards - about a minute every couple of hours. Btw I have limited the cpu frequency to 10 MHz - don't know if that can somehow affect the end result. Any ideas how to fix the time inaccuracy? I've seen the similar post about that but with deep sleep (without resolution) - this one is related to light sleep and I leave the XTAL oscillator on - that doesn't help for some reason...
The sleep function looks like that:
The sleep function looks like that:
- void lightSleep(int tm) {
- bool is_in_light_sleep=false;
- if(tm <= 0) tm = DEFAULT_LIGHT_SLEEP_TIME_S * uS_TO_S_FACTOR;
- else tm *= uS_TO_S_FACTOR;
- esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);//!< RTC IO, sensors and ULP co-processor
- esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_ON);//!< XTAL oscillator
- esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL);
- for(gpio_num_t button_pin : buttons){
- if(gpio_wakeup_enable(button_pin, GPIO_INTR_LOW_LEVEL) != ESP_OK) {
- Serial.print("Error setting up the wakeup pin '");
- Serial.print(button_pin);
- Serial.println("'!");
- }
- }
- //https://github.com/espressif/arduino-esp32/issues/5107
- PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_GPIO3);
- if(gpio_wakeup_enable(GPIO_NUM_3, GPIO_INTR_LOW_LEVEL) != ESP_OK) {
- Serial.println("Error setting UART via GPIO pin '3' wakeup!");
- is_in_light_sleep = false;
- return;
- }
- is_in_light_sleep = true;
- if(esp_sleep_enable_gpio_wakeup() != ESP_OK) {
- Serial.println("Error setting gpio wakeup!");
- is_in_light_sleep = false;
- return;
- }
- if(tm > 0)
- if(esp_sleep_enable_timer_wakeup(tm) != ESP_OK) {
- Serial.println("Error setting timer wakeup!");
- is_in_light_sleep = false;
- return;
- }
- Serial.println("Starting light sleep.");
- Serial.print("Sleep time set to ");
- Serial.print(round(tm/uS_TO_S_FACTOR));
- Serial.println(" seconds.");
- Serial.flush();
- delay(100); // https://rntlab.com/question/how-to-use-esp32-light-sleep/
- esp_err_t t = esp_light_sleep_start();
- if(t != ESP_OK) {
- Serial.println("Sleep mode NOT enabled due to an error!");
- }
- Serial.println("Back from light sleep!");
- PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_U0RXD); // https://github.com/espressif/arduino-esp32/issues/5107
- if(is_in_light_sleep) {
- 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;
- case ESP_SLEEP_WAKEUP_GPIO : Serial.println("Wakeup caused by GPIO interruption"); break;
- case ESP_SLEEP_WAKEUP_UART : Serial.println("Wakeup caused by UART"); break;
- //case ESP_SLEEP_WAKEUP_BT : Serial.println("Wakeup caused by Bluetooth"); break;
- //case ESP_SLEEP_WAKEUP_WIFI : Serial.println("Wakeup caused by WiFi"); break;
- default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
- }
- is_in_light_sleep = false;
- }
- }