In the Deep Sleep mode of the ESP32, data in ordinary memory is lost because the main CPU and most peripherals are powered off. However, RTC Memory (RTC Slow/Fast Memory) and non-volatile storage (such as Flash/NVS) can be used to preserve data during sleep. Below are detailed methods and considerations for data preservation:
1. Data Preservation in RTC Memory
RTC Memory (RTC Slow/Fast Memory) remains powered during deep sleep, making it suitable for storing temporary runtime data (such as counters, status flags, etc.).
1.1 Using <span>RTC_DATA_ATTR</span> to Preserve Data
By using the macro <span>RTC_DATA_ATTR</span>, variables can be declared in RTC memory to ensure data is retained after deep sleep.
#include "esp_sleep.h"
// Define RTC memory variable (value retained after wakeup)
RTC_DATA_ATTR int bootCount = 0; // Record wakeup count
void setup() {
Serial.begin(115200);
delay(1000);
// Configure wakeup source (example: timer wakeup)
esp_sleep_enable_timer_wakeup(10 * 1000000); // Wake up after 10 seconds
// Print wakeup count after waking up
Serial.printf("Wakeup count: %d\n", ++bootCount);
esp_deep_sleep_start();
}
void loop() {}
1.2 Limitations of RTC Memory
- Capacity Limit The RTC Slow Memory of the ESP32 typically has only 8 KB, suitable for storing small data.
- Access Speed RTC memory access speed is relatively slow and not suitable for frequent read/write of large data.
- Data Types Only basic data types (such as
<span>int</span>,<span>float</span>,<span>bool</span>, etc.) are supported.
2. Non-volatile Storage (Flash/NVS)
After deep sleep ends, the main memory is reset, so long-term data needs to be saved to non-volatile storage (Flash/NVS).
2.1 Using NVS to Save Data
NVS (Non-Volatile Storage) is a storage interface provided by ESP-IDF, suitable for saving WiFi credentials, device configurations, and other data.
#include "nvs_flash.h"
#include "nvs.h"
void save_data_to_nvs() {
nvs_handle_t my_handle;
esp_err_t err;
// Open NVS partition
err = nvs_open("storage", NVS_READWRITE, &my_handle);
if (err != ESP_OK) return;
// Write data (example: save wakeup count)
int wake_count = 5;
nvs_set_i32(my_handle, "wake_count", wake_count);
// Commit changes
nvs_commit(my_handle);
nvs_close(my_handle);
}
void read_data_from_nvs() {
nvs_handle_t my_handle;
esp_err_t err;
err = nvs_open("storage", NVS_READONLY, &my_handle);
if (err != ESP_OK) return;
// Read data
int wake_count = 0;
nvs_get_i32(my_handle, "wake_count", &wake_count);
Serial.printf("Wakeup count read from NVS: %d\n", wake_count);
nvs_close(my_handle);
}
2.2 Using Flash to Store Data
Directly operate Flash partitions to save data (suitable for advanced users):
#include "esp_flash.h"
void write_to_flash() {
uint32_t data = 0x12345678;
esp_flash_write(FLASH_DEVICE, &data, 0x1000, sizeof(data)); // Write to Flash address 0x1000
}
void read_from_flash() {
uint32_t data = 0;
esp_flash_read(FLASH_DEVICE, &data, 0x1000, sizeof(data)); // Read from Flash address 0x1000
Serial.printf("Data read from Flash: 0x%x\n", data);
}
3. Wake Stub
The wake stub is a code snippet that executes immediately after waking up, suitable for quickly saving sensor data or triggering wake conditions.
3.1 Configuring the Wake Stub
The wake stub needs to reside in RTC memory and execute immediately after waking up:
#include "esp_sleep.h"
// Wake stub function (executes immediately after waking up)
void RTC_IRAM_ATTR wake_stub() {
// Example: Read ADC sensor data and save to RTC memory
uint32_t sensor_value = 0;
adc_read(&sensor_value);
RTC_DATA_ATTR uint32_t rtc_sensor_value = sensor_value;
}
void setup() {
// Register wake stub
esp_sleep_set_wake_stub(wake_stub);
// Configure wakeup source (example: timer wakeup)
esp_sleep_enable_timer_wakeup(5 * 1000000); // Wake up after 5 seconds
esp_deep_sleep_start();
}
void loop() {}
3.2 Limitations of the Wake Stub
- Code Size The wake stub code must be less than 8 KB (limited by RTC memory).
- Function Limitations Can only access RTC peripherals (such as RTC GPIO, ADC, temperature sensors, etc.).
4. Typical Application Scenarios for Data Preservation
| Scenario | Preservation Method | Example |
|---|---|---|
| Wakeup Count Tracking | RTC Memory | <span>RTC_DATA_ATTR int bootCount = 0;</span> |
| WiFi Connection Status | NVS | Save SSID and password to NVS |
| Sensor Data Buffering | RTC Memory + Flash | Temporarily save sensor data to RTC, write to Flash after waking up |
| ULP Coprocessor Monitoring Data | RTC Memory | ULP program writes data to RTC memory |
| Long-term Configuration Parameters | NVS | Save device configurations (such as sampling intervals, thresholds) |
5. Key Considerations
- RTC Memory Data Lifecycle
- Data is retained after waking up but lost after power off.
- RTC data needs to be periodically backed up to Flash/NVS.
- Flash write lifespan is about 100,000 times; frequent writes need optimization.
- Use
<span>esp_rom_printf()</span>to print debug information in the wake stub (note serial initialization).
- Data integrity needs to be verified after waking up (e.g., checksum).
6. Comprehensive Example: Saving Wakeup Count to NVS
#include "nvs_flash.h"
#include "esp_sleep.h"
RTC_DATA_ATTR int bootCount = 0; // RTC memory variable
void save_boot_count_to_nvs() {
nvs_handle_t my_handle;
nvs_open("storage", NVS_READWRITE, &my_handle);
nvs_set_i32(my_handle, "boot_count", bootCount);
nvs_commit(my_handle);
nvs_close(my_handle);
}
void read_boot_count_from_nvs() {
nvs_handle_t my_handle;
nvs_open("storage", NVS_READONLY, &my_handle);
nvs_get_i32(my_handle, "boot_count", &bootCount);
nvs_close(my_handle);
}
void setup() {
// Initialize NVS
nvs_flash_init();
// Read wakeup count from NVS
read_boot_count_from_nvs();
Serial.begin(115200);
delay(1000);
// Configure wakeup source
esp_sleep_enable_timer_wakeup(10 * 1000000); // Wake up after 10 seconds
// Update wakeup count and save to NVS
bootCount++;
save_boot_count_to_nvs();
Serial.printf("Current wakeup count: %d\n", bootCount);
esp_deep_sleep_start();
}
void loop() {}
7. Summary of Applicable Scenarios
- RTC Memory is suitable for storing temporary runtime data (such as wakeup counts, sensor buffers).
- NVS/Flash is suitable for saving long-term configurations (such as WiFi credentials, device IDs).
- Wake Stub is suitable for quickly responding to wake events (such as sensor monitoring, emergency wake).
By effectively utilizing RTC memory and non-volatile storage, the ESP32 can achieve reliable data preservation and recovery in deep sleep mode, meeting the needs of low-power IoT devices.