Deep sleep and time accuracy

lesept
Posts: 38
Joined: Wed Jun 27, 2018 10:30 pm

Deep sleep and time accuracy

Postby lesept » Mon Feb 04, 2019 10:41 pm

I want to make a clock displaying the time as HH:MM on an e-paper display. The e-paper takes some time to refresh.
To save power, I put the ESP32 in deep sleep until the next plain minute to wake up and display the new time. My problem here is how to estimate accurately the sleep time?

For the first boot, I connect to a ntp server and set the time of the ESP32. I refresh the display and go to deep sleep.
I have seen that my method is not accurate as I can have up to 15 seconds drift in an hour.

I tried to simplify the code: set the time, go to deep sleep for 5 seconds, wake up and display the time on serial monitor. Even in this simple case, when comparing with the ntp website, I can see some drift. So maybe it's my time management which is wrong?

Here is the code, can anyone help me and explain what is wrong or show me how to keep an accurate time over a few hours?
Thanks for your help

Code: Select all

#include <Arduino.h>
#include <WiFi.h>
#include <WiFiMulti.h>
#include <HTTPClient.h>
#include <WiFiClientSecure.h>
RTC_DATA_ATTR int bootCount = 0;

void setClock() { // This part is copied from someone else
  configTime(0, 0, "pool.ntp.org", "time.nist.gov");
  Serial.print(F("Waiting for NTP time sync: "));
  time_t nowSecs = time(nullptr);
  while (nowSecs < 8 * 3600 * 2) {
    delay(500);
    Serial.print(F("."));
    yield();
    nowSecs = time(nullptr);
  }
  struct tm timeinfo;
  gmtime_r(&nowSecs, &timeinfo);
  Serial.print(F("Current time: "));
  Serial.print(asctime(&timeinfo));
}


WiFiMulti WiFiMulti;

void setup() {
  Serial.begin(115200);
  if (bootCount == 0) {
    bootCount++;
    WiFi.mode(WIFI_STA);
    WiFiMulti.addAP("xxx", "yyyyy");
    Serial.print("Waiting for WiFi to connect...");
    while ((WiFiMulti.run() != WL_CONNECTED)) Serial.print(".");
    Serial.println(" connected");
    setClock();
  }
  struct tm timeinfo;
  time_t now;
  time(&now);
  localtime_r(&now, &timeinfo);
  Serial.print(F("Current time: "));
  Serial.print(asctime(&timeinfo));
  delay(200);  // leave time to the serial monitor to display
  uint64_t sleep_time = 5000000; // 5 seconds
  esp_sleep_enable_timer_wakeup(sleep_time);
  esp_deep_sleep_start();
}

void loop() {}
I should add that this code is quite accurate if I do not put the ESP32 into deep sleep. I had it run overnight with almost no drift.

EDIT: I had it run all night and it now has 2 min 50 sec drift
The board is a LOLIN 32.

ESP_igrr
Posts: 2071
Joined: Tue Dec 01, 2015 8:37 am

Re: Deep sleep and time accuracy

Postby ESP_igrr » Tue Feb 05, 2019 12:54 pm

Assuming that "all night" is 8 hours, 2'50" drift would amount to less than 1%. Internal 150kHz clock is only 5% accurate. You may enable 32kHz XTAL or an external 32kHz oscillator to improve accuracy. At the moment you can not do this in Arduino IDE. You need to use Arduino as IDF component, and change the RTC clock in menuconfig.

lesept
Posts: 38
Joined: Wed Jun 27, 2018 10:30 pm

Re: Deep sleep and time accuracy

Postby lesept » Tue Feb 05, 2019 1:35 pm

Thanks
Actually, I spotted an error : i should have substracted the 200 ms of the delay from the sleep time, making it 4800000 us. I'll check that tonight !

Who is online

Users browsing this forum: No registered users and 50 guests