0

I'm trying to create a sensor sampling project using ESP32 ( battery, solar panel and temperature affects are not part of test right now to reduce external effects that may cause/ increase such behaviour ).

In current phase, I'm only testing the sleep & waking up process.

A short description: System wakes up after deep sleep cycle, connects to Wifi, MQTT, NTP - and checks if wake up time ( wake up value is stored in ׳RTC_DATA_ATTR long calc_waketime׳ variable from previous cycle ), posting IFTTT, goes to deep sleep for another 10 min. cycle.

The phenomena I wish to share is: The longer deep sleep is the NTP has few seconds drift which gets longer (again - NTP sync has a drift and not RTC clock).

I'm aware that wake time/ RTC drifts during deep sleep ( especially in ESP8266 chips that wake up can be not accurate in terms of minute - I'm using ESP32). Since ESP32 uses RTC, waking up is very accurate ( matter of seconds ). In order to wake up in exact time ( 18:00, 18:10, 18:20... every hour ) code connects to Wifi& NTP, and verify that wake time was as intended (comparing the epoch value that was stored during the end of previous cycle and current epoch time ) if it woke up earlier, it will got to sleep for that missing time.

But - What puzzles me is why updated NTP time ( which is not related what so ever to RTC drifts ), is drifted the longer to sleep is ( for comparison : when less than a minute - almost no drift, when sleeping for 10 minutes, 3 seconds drift, 20 minutes get up to 5 seconds drifts ).

Please see NOTE(1) to witness the drift in 10 min sleep.

Posting terminal output: some explantions: NOTE (1) displays the 3 seconds drift , NOTE(2) calculated time that was stored at previous wake cycle, NOTE (3) shows that that drift get synced during the code run - 594 sec for next wake 18:50:00.

18:39:58.032 -> 09B⸮⸮L⸮1U1V(⸮⸮⸮1m1m1F⸮Connecting to Xiaomi_D6C8 .... // WAKING UP
18:39:58.595 -> 192.168.3.186
18:39:59.013 -> now is: 1580575203               **// NOTE (1)**
18:39:59.013 -> sleep time was: 1580574611
18:39:59.048 -> expected wake time: 1580575200   // NOTE (2)
18:39:59.085 -> total time delta: 3
18:39:59.122 -> OK - WOKE UP after due time: 
18:39:59.419 -> Attempting MQTT connection...connected
18:40:04.544 -> Connecting to maker.ifttt.com
18:40:04.855 -> Request resource: /trigger/send_reading/with/key/cFLymB4JT9tlODsKLFn9TA
18:40:05.376 -> HTTP/1.1 200 OK
18:40:05.376 -> Date: Sat, 01 Feb 2020 16:40:05 GMT
18:40:05.414 -> Content-Type: text/html; charset=utf-8
18:40:05.447 -> Content-Length: 52
18:40:05.480 -> Connection: close
18:40:05.515 -> X-Top-SecreTTT: VG9vIGVhc3k/IElmIHlvdSBjYW4gcmVhZCB0aGlzLCBFbWFpbCB1cyBhdCBqb2JzK3NlY3JldEBpZnR0dC5jb20uIFdlIHdhbnQgTWFrZXJzLg==
18:40:05.619 -> Server: web_server
18:40:05.619 -> 
18:40:05.619 -> Congratulations! You've fired the send_reading event
18:40:05.689 -> closing connection
18:40:07.007 -> Last Sleep: 1580574611
18:40:07.007 -> Time left: 594                 // NOTE (3)
18:40:07.041 -> Going to DeepSleep for [594] sec

Relevant code:

void sleepNOW(int sec2sleep = 2700)
{
  char tmsg[30];
  sprintf(tmsg, "Going to DeepSleep for [%d] sec", sec2sleep);
  Serial.println(tmsg);
  // mqtt_pubmsg(tmsg);
  Serial.flush();
  esp_sleep_enable_timer_wakeup(sec2sleep * uS_TO_S_FACTOR);
  esp_deep_sleep_start();
}
bool getTime()
{
  delay(200);
  if (getLocalTime(&timeinfo))
  {
    time(&now1);
    delay(200);
    return 1;
  }
  else
  {
    return 0;
  }
}

bool check_awake_ontime()
{
  getTime();
  if (timeinfo.tm_year >= 120) // year 2020
  {
    if (lastsleeptime != 0)
    { // not first boot
      long current_boottime = now1;
      int t_delta = now1 - calc_waketime;
      // int t_delta1 = TIME_TO_SLEEP * 60 - (t_delta + TIME_AWAKE);
      Serial.print("now is: ");
      Serial.println(now1);
      Serial.print("sleep time was: ");
      Serial.println(lastsleeptime);
      Serial.print("expected wake time: ");
      Serial.println(calc_waketime);

      Serial.print("total time delta: ");
      Serial.println(t_delta);
      if (t_delta >= 0)
      {
        Serial.println("OK - WOKE UP after due time: ");
        return 1;
      }
      else
      {
        Serial.println("FAIL- woke up before time: ");
        sleepNOW(-1 * t_delta);
        return 0;
      }
    }
    else
    {
      return 1;
    }
  }
  else
  {
    return 0;
  }
}

inside setup()

#if USE_WIFI
  if (startWifi())
  {
    mqttConnect();
    startNTP();
#if USE_SLEEP
    check_awake_ontime();   // PLEASE PAY ATTN ONLY THIS LINE 
#endif
  }

inside loop()

#if USE_SLEEP
  if (millis() >= TIME_AWAKE * 1000)
  {
    getTime();

    Serial.print("Last Sleep: ");
    Serial.println(lastsleeptime);

    long clockCount = TIME_TO_SLEEP * 60 - (timeinfo.tm_min * 60 + timeinfo.tm_sec) % (TIME_TO_SLEEP * 60);
    // Serial.print(timeinfo.tm_hour);
    // Serial.print(":");
    // Serial.print(timeinfo.tm_min);
    // Serial.print(":");
    // Serial.print(timeinfo.tm_sec);
    // Serial.println("");
    Serial.print("Time left: ");
    Serial.println(clockCount);

    lastsleeptime = now1;
    calc_waketime = now1 + clockCount;

    sleepNOW(clockCount);
  }

I'm not posting entire code, but only relevant parts. Appreciate any help,

  • 1
    the NTP only sets the RTC. and NTP is not immediate – Juraj Feb 1 at 17:49
  • @Juraj would you recommend a delay ? since getTime() has 2 delays of 200 mili's – Guy . D Feb 1 at 17:50
  • 1
    5 seconds is usually enough. you can do a trick. reset the RTC time to 0 and then you can check if it is set by NTP already – Juraj Feb 1 at 17:52
  • @Juraj can you please explain how? – Guy . D Feb 1 at 18:03
  • 1
    sorry, I forgot that there is no API for setting the RTC time on esp32. arduino.stackexchange.com/questions/72010/… – Juraj Feb 1 at 18:15
0

As Juraj commented, a 2.5 [sec] delay, solved it, and NTP update was correct.

| improve this answer | |
  • It's OK to accept your own answer as the solution to the problem. – VE7JRO Mar 16 at 17:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.