ESP8266, Deep sleep and RTC

slaboure
Posts: 5
Joined: Thu Oct 10, 2024 5:19 pm

ESP8266, Deep sleep and RTC

Postby slaboure » Fri Oct 11, 2024 10:01 am

TLDR; When going into deep sleep, I need to "recompute" the actual time, but I cannot seem to find a way to do so semi-precisely.

Context: I am managing an old (remote) clock through electrical signals, so need to send an impulse every minute. I first obtain my time with wifi/NTP, then, to reduce power consumption, disable my wifi and rely on the internal clock for ~1 week before re-syncing with NTP (I have about 1.8 sec drift per week). To further improve consumption, I'd like to go in deep sleep for ~55 seconds or more, then send my electric signal to the clock, then back to deep sleep, etc. for a week, until I eventually sync back to NTP.

I did some prototyping with deep sleep, so, I created a program that gets time through NTP, then do a series of 100 deep-sleep/wake-up, then after 100x, I sync back to NTP and check the drift.

Here is what I use to store my last known time and deep sleep duration in RTC, stored just before going to deep sleep:
struct RTCData

Code: Select all

{
  uint32_t magic;
  timeval storedTime; // stores sec and micro-sec
  int deepSleepTime;  // how long am I going to sleep
  int iteration;            // counting to 100 before syncing to NTP to compute the drift
};
I've tried multiple ways to restore the clock as I wake up from deep sleep. First option with system_get_rtc_time and system_rtc_clock_cali_proc:

Code: Select all

      uint32_t RTC_Time;
      uint32_t SYS_Time = system_get_rtc_time();
      uint32_t cal_factor = system_rtc_clock_cali_proc();
      RTC_Time = SYS_Time / (((cal_factor * 1000) >> 12) / 1000);

      // Set the system time to the adjusted current time
      timeval tv = {rtcData.storedTime.tv_sec + rtcData.deepSleepTime, static_cast<suseconds_t>(rtcData.storedTime.tv_usec + RTC_TIME)};
I had big hopes but this is pretty bad, about 18 seconds drift over 100x (random duration of 3-8 sec sleeps)

Then went straight to "millis()" and it was better, about 9sec drift:

Code: Select all

      timeval tv = {rtcData.storedTime.tv_sec + rtcData.deepSleepTime, static_cast<suseconds_t>(rtcData.storedTime.tv_usec + millis() * 1000)};
Lastly, I correct with a static value and it is "perfect" time-wise

Code: Select all

      timeval tv = {rtcData.storedTime.tv_sec + rtcData.deepSleepTime, static_cast<suseconds_t>(rtcData.storedTime.tv_usec + millis() * 1000 + 120 * 1000)};
But obviously, it is super ugly and non-deterministic.

What am I missing? How can I get the true time that elapses, beyond the actual sleep time? I need this "time" that elapses.

Would a ESP32-C6 have a better way to solve this?

(I don't want to use an external RTC)

Happy to send the code if useful!

Thanks!

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

Re: ESP8266, Deep sleep and RTC

Postby ESP_Sprite » Sat Oct 12, 2024 3:33 am

I don't think the ESP8266 can use an external 32KHz crystal, so it relies on an internal clock that can drift pretty bad (+/- 5% or something, if memory serves, maybe even worse). An ESP32-C6 can have an external 32KHz crystal attached to it, lowering the drift to that of the crystal (usually something like 10ppm). Also, depending on how low you need to go (are you running off a battery?), with the ESP32-C6 you can have the ULP do the pulse generation, meaning you only need to wake the main processor to sync to NTP.

slaboure
Posts: 5
Joined: Thu Oct 10, 2024 5:19 pm

Re: ESP8266, Deep sleep and RTC

Postby slaboure » Mon Oct 14, 2024 8:49 am

Thanks! The 8266 internal clock was actually pretty good based on my measurements (about 265ms per day, so manageable), but the deep sleep makes it hard to connect the dot, as discussed, as I don't have a way to evaluate the time spent probably between going to sleep and recovery (anything that "millis()" wouldn't count essentially), so the precision is not much the problem, more of the lack of counted cycles.

Great great great feedback on the ULP, I wasn't aware of it and it seems great! Read a ton about it, very intriguing! Thanks for the reference/idea, I love it!

Who is online

Users browsing this forum: No registered users and 4 guests