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,
getTime()
has 2 delays of 200 mili's