Hi everybody,
As discussed in this thread
The RTC-time drifts away pretty fast when the ESP32 is in a sleep-mode.
I'm still working on getting an ESP32 to RE-sync with an NTP-server when coming back from deepsleep.
What I have managed so far is to get the actual time from an NTP-server on boot.
But it seems to be different when the ESP32 wakes up from deepsleep.
The callback-function
void SNTP_Time_received(struct timeval *t) {
Serial.println("callback Got time adjustment from NTP!");
timeIsSynchronised = true;
}
is not called again when awaking from deepsleep
// MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START *
// a detailed explanation how these macros work is given in this tutorial
// https://forum.arduino.cc/t/comfortable-serial-debug-output-short-to-write-fixed-text-name-and-content-of-any-variable-code-example/888298
#define dbg(myFixedText, variableName) \
Serial.print( F(#myFixedText " " #variableName"=") ); \
Serial.println(variableName);
#define dbgi(myFixedText, variableName,timeInterval) \
{ \
static unsigned long intervalStartTime; \
if ( millis() - intervalStartTime >= timeInterval ){ \
intervalStartTime = millis(); \
Serial.print( F(#myFixedText " " #variableName"=") ); \
Serial.println(variableName); \
} \
}
#define dbgc(myFixedText, variableName) \
{ \
static long lastState; \
if ( lastState != variableName ){ \
Serial.print( F(#myFixedText " " #variableName" changed from ") ); \
Serial.print(lastState); \
Serial.print( F(" to ") ); \
Serial.println(variableName); \
lastState = variableName; \
} \
}
#define dbgcf(myFixedText, variableName) \
{ \
static float lastState; \
if ( lastState != variableName ){ \
Serial.print( F(#myFixedText " " #variableName" changed from ") ); \
Serial.print(lastState); \
Serial.print( F(" to ") ); \
Serial.println(variableName); \
lastState = variableName; \
} \
}
// MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END *
#define uS_TO_S_FACTOR 1000000 /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP 60 /* Time ESP32 will go to sleep (in seconds) */
RTC_DATA_ATTR int bootCount = 0;
#include <WiFi.h>
#include <sntp.h>
#include <time.h> // time() ctime()
time_t now; // this is the epoch
tm myTimeInfo; // the structure tm holds time information in a more convient way
boolean timeIsSynchronised;
unsigned long MyTestTimer = 0; // variables MUST be of type unsigned long
const byte OnBoard_LED = 2;
unsigned long myGotoDeepSleepTimer;
const char *ssid = "FRITZ!Box 4060 TR";
const char *password = "";
const char* ntpServer = "fritz.box";
const long gmtOffset_sec = 0;
const int daylightOffset_sec = 7200;
void print_wakeup_reason() {
esp_sleep_wakeup_cause_t wakeup_reason;
wakeup_reason = esp_sleep_get_wakeup_cause();
switch (wakeup_reason)
{
case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
default : Serial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason); break;
}
}
void showTime() {
time(&now); // read the current time
localtime_r(&now, &myTimeInfo); // update the structure tm with the current time
Serial.print("year:");
Serial.print(myTimeInfo.tm_year + 1900); // years since 1900
Serial.print("\tmonth:");
Serial.print(myTimeInfo.tm_mon + 1); // January = 0 (!)
Serial.print("\tday:");
Serial.print(myTimeInfo.tm_mday); // day of month
Serial.print("\thour:");
Serial.print(myTimeInfo.tm_hour); // hours since midnight 0-23
Serial.print("\tmin:");
Serial.print(myTimeInfo.tm_min); // minutes after the hour 0-59
Serial.print("\tsec:");
Serial.print(myTimeInfo.tm_sec); // seconds after the minute 0-61*
Serial.print("\twday");
Serial.print(myTimeInfo.tm_wday); // days since Sunday 0-6
if (myTimeInfo.tm_isdst == 1) // Daylight Saving Time flag
Serial.print("\tDST");
else
Serial.print("\tstandard");
Serial.println();
}
void connectToWifi() {
Serial.print("Connecting to #");
Serial.print(ssid);
Serial.println("#");
WiFi.persistent(false);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
int myCount = 0;
while (WiFi.status() != WL_CONNECTED) {
yield();
BlinkHeartBeatLED(OnBoard_LED, 333);
delay(332);
myCount++;
Serial.print(".");
if (myCount > 100) {
Serial.println();
Serial.println("no connection yet ESP.restart()");
ESP.restart();
}
}
Serial.print("\n connected.");
Serial.println(WiFi.localIP() );
}
void synchroniseWith_NTP_Time() {
Serial.print("synchroniseWith_NTP_Time configTime uses ntpServer ");
Serial.println(ntpServer);
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
Serial.print("synchronising time");
int myCount = 0;
while ( !timeIsSynchronised && myCount < 100) {
myCount++;
yield();
time(&now); // read the current time
localtime_r(&now, &myTimeInfo);
BlinkHeartBeatLED(OnBoard_LED, 200);
delay(201);
Serial.print(".");
if (myCount % 20 == 0) {
showTime();
}
}
if (timeIsSynchronised) {
Serial.print("\n time synchronsized \n");
showTime();
}
if (myCount >= 100) {
Serial.print("\n sync did not occur ESP.restart() \n");
ESP.restart();
}
}
void PrintFileNameDateTime() {
Serial.println( F("Code running comes from file ") );
Serial.println(__FILE__);
Serial.print( F(" compiled ") );
Serial.print(__DATE__);
Serial.print( F(" ") );
Serial.println(__TIME__);
}
boolean TimePeriodIsOver (unsigned long &periodStartTime, unsigned long TimePeriod) {
unsigned long currentMillis = millis();
if ( currentMillis - periodStartTime >= TimePeriod )
{
periodStartTime = currentMillis; // set new expireTime
return true; // more time than TimePeriod) has elapsed since last time if-condition was true
}
else return false; // not expired
}
void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {
static unsigned long MyBlinkTimer;
pinMode(IO_Pin, OUTPUT);
if ( TimePeriodIsOver(MyBlinkTimer, BlinkPeriod) ) {
digitalWrite(IO_Pin, !digitalRead(IO_Pin) );
}
}
//Callback-function
void SNTP_Time_received(struct timeval *t) {
Serial.println("callback Got time adjustment from NTP!");
timeIsSynchronised = true;
}
void setup() {
timeIsSynchronised = false;
Serial.begin(115200);
delay(1000);
Serial.println("\n Setup-Start \n");
PrintFileNameDateTime();
sntp_set_time_sync_notification_cb( SNTP_Time_received ); // set notification call-back function
if (bootCount == 0) {
connectToWifi();
}
else {
Serial.print("bootcount=");
Serial.println(bootCount);
Serial.println(" reconnect() to WiFi");
WiFi.reconnect();
Serial.println(" reconnect() done");
}
synchroniseWith_NTP_Time();
++bootCount;
Serial.println("Boot number: " + String(bootCount));
//Print the wakeup reason for ESP32
print_wakeup_reason();
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) + " Seconds");
Serial.println("Going to sleep in 3 seconds");
myGotoDeepSleepTimer = millis();
}
void loop() {
BlinkHeartBeatLED(OnBoard_LED, 100);
if ( TimePeriodIsOver(MyTestTimer, 1000) ) {
showTime();
}
if ( TimePeriodIsOver(myGotoDeepSleepTimer, 3000) ) {
Serial.print("sleeping now for ");
Serial.print(TIME_TO_SLEEP);
Serial.println(" seconds");
esp_deep_sleep_start();
Serial.println("This will never be printed");
}
}
What do I have to change / to add in this code to force the ESP32 to make a new NTP-server-request?
a new call to
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
does not do the trick
best regards Stefan
