How does light sleep work?

Ahmetsafi
Posts: 10
Joined: Wed Aug 07, 2024 12:01 pm

How does light sleep work?

Postby Ahmetsafi » Wed Aug 28, 2024 10:15 pm

Hi there,

I am working on a low-power project using the ESP32-C3, where the product will be configurable by the user. As part of this project, I plan to utilize both light sleep and deep sleep modes. During my tests, I observed something interesting about the light sleep mode, and I wanted to clarify my findings.

According to the ESP32-C3 datasheet and the "Sleep Modes" section in the ESP-IDF API references, it is mentioned that Wi-Fi is supposed to disconnect when light sleep is enabled, and the application must manage this. However, in my current implementation, I am using light sleep with periods of less than 60 seconds, without explicitly stopping Wi-Fi or Bluetooth. Surprisingly, I found that Wi-Fi does not disconnect from the Access Point (AP). As a result, when the ESP32 wakes from sleep, it can immediately take sensor data and send it over MQTT, usually within a second. This seems to be very efficient, as I measured the current consumption and found it drops to 130 microamperes, consistent with the datasheet specifications.

This working mode seems quite effective, especially since modem sleep appears to consume more power during sleep periods of around 30 seconds, and deep sleep takes too much time to reinitialize all the peripherals. However, my concern is that this approach is not mentioned or recommended anywhere, and the API reference suggests that the application must stop Wi-Fi and Bluetooth before entering light sleep.

Could this approach cause any issues in the future, or are there any potential risks associated with not explicitly stopping Wi-Fi and Bluetooth before entering light sleep?

Thank you for your time and assistance.
Attachments
Screenshot from 2024-08-29 01-02-45.png
Screenshot from 2024-08-29 01-02-45.png (219.86 KiB) Viewed 847 times

ESP_Sprite
Posts: 9709
Joined: Thu Nov 26, 2015 4:08 am

Re: How does light sleep work?

Postby ESP_Sprite » Thu Aug 29, 2024 12:30 am

Issue, I think, is that it works *in this case*. When you enter light sleep manually, the WiFi base station has no idea you're doing so, and it might disconnect you if it runs into a timeout and needs to send you a packet. If you use automatic light sleep instead, the WiFi stack will coordinate sleeping with the power management logic, and we can guarantee the ESP will stay connected (given a base station with proper WiFi implementation).

Ahmetsafi
Posts: 10
Joined: Wed Aug 07, 2024 12:01 pm

Re: How does light sleep work?

Postby Ahmetsafi » Thu Aug 29, 2024 7:28 am

ESP_Sprite wrote:
Thu Aug 29, 2024 12:30 am
Issue, I think, is that it works *in this case*. When you enter light sleep manually, the WiFi base station has no idea you're doing so, and it might disconnect you if it runs into a timeout and needs to send you a packet. If you use automatic light sleep instead, the WiFi stack will coordinate sleeping with the power management logic, and we can guarantee the ESP will stay connected (given a base station with proper WiFi implementation).
Yes i also think issue is how ESP32 manage to keep wi-fi connection? Here is my code:
#include "main.h"
#include "esp_vfs_semihost.h"
#include "esp_vfs_fat.h"
#include "esp_spiffs.h"
#include "sdmmc_cmd.h"
#include "soc/soc_caps.h"
#include "freertos/semphr.h"
#include "driver/uart.h"
#include "esp_timer.h"
#include "esp_check.h"
#include "ble_init.h"

#define RESET_SCD41_NVS_ENTRY 0
#define DEEP_SLEEP_LOW_POWER 0
#define TIMER_WAKEUP_TIME_US 10000000

static RTC_DATA_ATTR struct timeval sleep_enter_time;
static const char *TAG = "SENSOR";
TaskHandle_t i2cTaskHandle = NULL;

typedef struct {
uint16_t co2;
float temperature;
float humidity;
} sensor_data_t;

sensor_data_t sensor_data = {0};

void scd4x_read_measurements_task(void *pvParameters)
{
sensor_data_t *sensor_data = (sensor_data_t *)pvParameters;
esp_err_t ret;

mainTaskHandle = xTaskGetCurrentTaskHandle();

while (1) {
ret = scd4x_read_measurement(&(sensor_data->co2), &(sensor_data->temperature), &(sensor_data->humidity));
if (ret == ESP_OK) {
ESP_LOGI(TAG, "CO2: %u ppm, Temperature: %.2f C, Humidity: %.2f%%",
sensor_data->co2, sensor_data->temperature, sensor_data->humidity);
// Create JSON object
cJSON *root = cJSON_CreateObject();
cJSON_AddNumberToObject(root, "temperature", sensor_data->temperature);
cJSON_AddNumberToObject(root, "humidity", sensor_data->humidity);
cJSON_AddNumberToObject(root, "CO2", sensor_data->co2);
char *jsonString = cJSON_Print(root);

esp_mqtt_client_publish(mqtt_client, "sensor/scd4x", jsonString, strlen(jsonString), 1, 0);

cJSON_Delete(root);
if (jsonString) {
free(jsonString);
}
ESP_LOGI(TAG, "UYKUDAN ÇIKTI.");
ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(5000));

} else {
ESP_LOGE(TAG, "Failed to read measurement");
}
}
}

static void example_deep_sleep_register_rtc_timer_wakeup(void)
{
uint64_t u64SleepLength = 3600ULL * 1000000ULL;
const int wakeup_time_sec = 3600;
ESP_LOGI(TAG, "Enabling timer wakeup, %ds", wakeup_time_sec);
ESP_ERROR_CHECK(esp_sleep_enable_timer_wakeup(u64SleepLength));
}

esp_err_t example_register_timer_wakeup(void)
{
uint64_t u64SleepLength = 10ULL * 1000000ULL; // 10 seconds in microseconds
ESP_RETURN_ON_ERROR(esp_sleep_enable_timer_wakeup(u64SleepLength), TAG, "Configure timer as wakeup source failed");
ESP_LOGI(TAG, "timer wakeup source is ready");
return ESP_OK;
}

void app_main(void)
{
esp_err_t ret;

// Initialize NVS
ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);

ESP_ERROR_CHECK(i2c_master_init());
ESP_LOGI(TAG, "I2C initialized successfully");
scd4x_stop_periodic_measurement();
vTaskDelay(1000 / portTICK_PERIOD_MS);

scd4x_start_periodic_measurement();
example_register_timer_wakeup();
ble_app();
mqtt_app_start();
wifi_connection();
vTaskDelay(5000 / portTICK_PERIOD_MS);

xTaskCreate(scd4x_read_measurements_task, "SCD4X_TASK", 8192, &sensor_data, 5, &i2cTaskHandle);
}
i use "esp_light_sleep_start" function in MQTT event.
case MQTT_EVENT_PUBLISHED:
ESP_LOGI(MQTT_TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
// Sleep immediately after the data is published
ESP_LOGI(MQTT_TAG, "Data sent, entering light sleep mode");
vTaskDelay(pdMS_TO_TICKS(100));

esp_light_sleep_start();

// Notify the main task that the publish event has occurred
if (mainTaskHandle != NULL) {
xTaskNotifyGive(mainTaskHandle);
}
break;
With this setup i can take sensor value and send it over MQTT around 0.2 second. When i set sleep time more than 50 seconds wifi disconnect and when esp32 wake up it must reconnect wifi. Here is output of my code:
I (13289) wifi:bcn_timeout,ap_probe_send_start
I (13289) SCD4X: Raw data: 07 52 33 67 69 49 6D 20 12
I (13289) SENSOR: CO2: 1874 ppm, Temperature: 25.69 C, Humidity: 42.63%
I (13299) SENSOR: UYKUDAN ÇIKTI.
I (13629) MQTT_CLIENT: MQTT_EVENT_PUBLISHED, msg_id=16050
I (13629) MQTT_CLIENT: Data sent, entering light sleep mode
I (13729) SCD4X: Raw data: 07 55 A4 67 4A 9C 6D 99 25
I (13729) SENSOR: CO2: 1877 ppm, Temperature: 25.61 C, Humidity: 42.81%
I (13739) SENSOR: UYKUDAN ÇIKTI.
I (18739) SCD4X: Raw data: 07 4D 5E 67 32 DD 6D E0 55
I (18739) SENSOR: CO2: 1869 ppm, Temperature: 25.54 C, Humidity: 42.92%
I (18739) SENSOR: UYKUDAN ÇIKTI.
I (23739) SCD4X: Raw data: 07 4B F8 67 20 FC 6E 09 31
I (23739) SENSOR: CO2: 1867 ppm, Temperature: 25.50 C, Humidity: 42.98%
I (23739) SENSOR: UYKUDAN ÇIKTI.
I (28739) SCD4X: Raw data: 07 47 85 67 0F 54 6E 55 32
I (28739) SENSOR: CO2: 1863 ppm, Temperature: 25.45 C, Humidity: 43.10%
I (28739) SENSOR: UYKUDAN ÇIKTI.
I (33739) SCD4X: Raw data: 07 44 D6 66 FB E6 6E 80 C3
I (33739) SENSOR: CO2: 1860 ppm, Temperature: 25.40 C, Humidity: 43.16%
I (33739) SENSOR: UYKUDAN ÇIKTI.
I (38479) MQTT_CLIENT: MQTT_EVENT_PUBLISHED, msg_id=64577
I (38479) MQTT_CLIENT: Data sent, entering light sleep mode
I (38579) SCD4X: Raw data: 07 4A C9 66 DA 51 6E FD 77
I (38579) SENSOR: CO2: 1866 ppm, Temperature: 25.31 C, Humidity: 43.36%
I (38589) SENSOR: UYKUDAN ÇIKTI.
I (38799) MQTT_CLIENT: MQTT_EVENT_PUBLISHED, msg_id=37386
I (38799) MQTT_CLIENT: Data sent, entering light sleep mode
I (38899) wifi:bcn_timeout,ap_probe_send_start
I (38899) SCD4X: Raw data: 07 4E 0D 66 D0 8A 6F 5F 1D
I (38899) SENSOR: CO2: 1870 ppm, Temperature: 25.28 C, Humidity: 43.50%
I (38909) SENSOR: UYKUDAN ÇIKTI.
I (38939) MQTT_CLIENT: MQTT_EVENT_PUBLISHED, msg_id=48978
I (38939) MQTT_CLIENT: Data sent, entering light sleep mode
I (39039) SCD4X: Raw data: 07 51 60 66 B8 88 6F 74 71
I (39039) SENSOR: CO2: 1873 ppm, Temperature: 25.22 C, Humidity: 43.54%
I (39049) SENSOR: UYKUDAN ÇIKTI.
I (39059) MQTT_CLIENT: MQTT_EVENT_PUBLISHED, msg_id=5969
I (39059) MQTT_CLIENT: Data sent, entering light sleep mode
I (39159) wifi:bcn_timeout,ap_probe_send_start

Who is online

Users browsing this forum: MicroController and 249 guests