From 82d3cb7dd2cb0afe2d4c9fd834d9449dfb7fc0f7 Mon Sep 17 00:00:00 2001 From: Vitalii Stepchyk Date: Tue, 23 Jan 2024 20:23:20 +0100 Subject: [PATCH] Add example for avoiding buffer re-initialization after waking up from deep sleep mode --- README.md | 38 ++++++++- .../DeepSleepPersistence.ino | 85 +++++++++++++++++++ 2 files changed, 119 insertions(+), 4 deletions(-) create mode 100644 examples/DeepSleepPersistence/DeepSleepPersistence.ino diff --git a/README.md b/README.md index 22ff979..22ea9b1 100644 --- a/README.md +++ b/README.md @@ -117,7 +117,7 @@ Note: this operator is not interrupt safe. If you need to access a circular buff ### Add an element with error handling -``` +```ino RingBuf myBuffer; void setup() @@ -131,7 +131,7 @@ void setup() ### Process an element if available -``` +```ino RingBuf myBuffer; void setup() @@ -146,7 +146,7 @@ void setup() ### Fill a buffer with values from 10 to 1 then print all the elements -``` +```ino #include RingBuf myBuffer; @@ -167,7 +167,7 @@ void loop() ``` ### Fill a buffer with values from 10 to 1 then pop and peek the next element -``` +```ino #include RingBuf myBuffer; @@ -188,6 +188,36 @@ void setup() } } +void loop() +{ +} +``` +### Skip buffer initialization in ESP32 RTC memory when executed after wakeup from deep sleep + +```ino +#include + +RTC_DATA_ATTR uint32_t wakeupCounter = 0; +RTC_DATA_ATTR RingBuf myBuffer([]() -> bool { + return esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_UNDEFINED; +}); + +void setup() +{ + Serial.begin(115200); + Serial.print("Wakeup! #"); + Serial.println(++wakeupCounter); + myBuffer.pushOverwrite(wakeupCounter); + + Serial.print("myBuffer: "); + for (uint8_t i = 0; i < myBuffer.size(); ++i) { + Serial.print(myBuffer[i]); Serial.print(" "); + } + Serial.println(); + Serial.flush(); + esp_deep_sleep(5000000); +} + void loop() { } diff --git a/examples/DeepSleepPersistence/DeepSleepPersistence.ino b/examples/DeepSleepPersistence/DeepSleepPersistence.ino new file mode 100644 index 0000000..de9a72b --- /dev/null +++ b/examples/DeepSleepPersistence/DeepSleepPersistence.ino @@ -0,0 +1,85 @@ +/* + This demo showcases the use of the constructor callback initHelper + to control whether RingBuf should initialize its internal counters. + This is useful when you need to put the controller to deep sleep + and whant the data in the buffer to be preserved in the RTC memory. + In this example ESP32 functions are used to put the controller to + ultra low power mode, and to check whether it is initial run or + the code executes after wake-up. + + Without it the buffer will start over after each wakeup, like this: + + Wakeup! #1 + myBuffer-before: [] + myBuffer-after: [1, ] + Sleeping... + + Wakeup! #2 + myBuffer-before: [] + myBuffer-after: [2, ] + Sleeping... + + Wakeup! #3 + myBuffer-before: [] + myBuffer-after: [3, ] + Sleeping... + + But with the callback configured, the output shows that the data + is persisted between weakeups: + + Wakeup! #1 + myBuffer-before: [] + myBuffer-after: [1, ] + Sleeping... + + Wakeup! #2 + myBuffer-before: [1, ] + myBuffer-after: [1, 2, ] + Sleeping... + + Wakeup! #3 + myBuffer-before: [1, 2, ] + myBuffer-after: [1, 2, 3, ] + Sleeping... + */ + +#include + +// store the counter in the RTC memory +RTC_DATA_ATTR uint32_t wakeupCounter = 0; + +// store the buffer in the RTC memory +RTC_DATA_ATTR RingBuf myBuffer([]() -> bool { + // Check whether the code is being executed after wakeup + return esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_UNDEFINED; +}); + +void setup() { + Serial.begin(115200); + Serial.print("Wakeup! #"); + Serial.println(++wakeupCounter); + + Serial.print("myBuffer-before: ["); + for (uint8_t i = 0; i < myBuffer.size(); ++i) { + Serial.print(myBuffer[i]); Serial.print(", "); + } + Serial.println("]"); + + myBuffer.pushOverwrite(wakeupCounter); + + Serial.print("myBuffer-after: ["); + for (uint8_t i = 0; i < myBuffer.size(); ++i) { + Serial.print(myBuffer[i]); Serial.print(", "); + } + Serial.println("]"); + + Serial.println("Sleeping..."); + Serial.flush(); + + // sleep 5 seconds + esp_deep_sleep(5000000); +} + +void loop() { + // never executed +}