I've Googled myself tired on this topic and I see that NTP time synchronization discussions are plentiful in the forums here, so apologies if I am asking a question that has been answered - I really tried to solve this myself lol.
I am building an ESP32 based project that needs to trigger a relay on a schedule. The time needs to be accurate and NTP seems like a reasonable solution. I understand that the default ESP32 time.h library includes everything needed to make that work. No problem there.
The confusion comes about because I have found references and examples to NTP synchronized local time both with and without additional NTP updates - many examples rely on the default 1 hour automatic NTP synch, while others turn off WiFi after the initial synch so the system time will drift at some point. I cannot seem to locate the API reference that identifies whether that automatic re-synch occurs or not. Or, perhaps the NTP code in time.h sees that the network is no longer active and just skips any future periodic updates. I do see a reference in this post to the Espressif API suggesting that the interval may be changed by modifying a variable named CONFIG_LWIP_SNTP_UPDATE_DELAY, but I'm uncertain how to set that variable and also the minimum is stated as 15 sec, so that obviously is not how the updates are disabled if that is desired.
Finally - my project displays the time with seconds, so I need a loop that occurs every second. Here is another area that is confusing because many examples seem to solve it differently and I have no idea what would be 'right' or 'wrong' here. This is what I've come up with -
i#include <WiFi.h>
#include <time.h>
#include <M5DinMeter.h> // My board defs
int LastSecond;
const char* NTP_SERVER = "us.pool.ntp.org";
const char* TZ_INFO = "EST5EDT"; // enter your time zone (https://remotemonitoringsystems.ca/time-zone-abbreviations.php)
tm timeinfo;
time_t now;
long unsigned lastNTPtime;
unsigned long lastEntryTime;
void setup() {
Serial.begin(115200);
while (!Serial) { ; } // wait for Serial port to connect. Needed for native USB port only
WiFi.begin(ssid, password);
int counter = 0;
while (WiFi.status() != WL_CONNECTED) {
delay(200);
if (++counter > 100) ESP.restart();
Serial.print ( "." );
}
Serial.println("\n\nWiFi connected\n\n");
configTime(0, 0, NTP_SERVER);
// See https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv for Timezone codes for your region
setenv("TZ", TZ_INFO, 1);
if (getNTPtime(10)) { // wait up to 10sec to sync
} else {
Serial.println("Time not set");
ESP.restart();
}
showTime(timeinfo);
lastNTPtime = time(&now);
lastEntryTime = millis();
}
void loop() {
getNTPtime(10);
showTime(timeinfo); // FOO update display with localtime(&now)
//delay(1000);
while (LastSecond == timeinfo.tm_sec) {
time(&now);
localtime_r(&now, &timeinfo);
}
LastSecond = timeinfo.tm_sec;
}
bool getNTPtime(int sec) {
{
uint32_t start = millis();
do {
time(&now);
localtime_r(&now, &timeinfo);
Serial.print(".");
delay(10);
} while (((millis() - start) <= (1000 * sec)) && (timeinfo.tm_year < (2016 - 1900)));
if (timeinfo.tm_year <= (2016 - 1900)) return false; // the NTP call was not successful
// Serial.print("now "); Serial.println(now);
// char time_output[30];
// strftime(time_output, 30, "%a %d-%m-%y %T", localtime(&now));
// Serial.println(time_output);
// Serial.println();
}
return true;
}
I have not included any code related to running my tasks as the main issue is just getting a simple loop that runs every second. Additionally, I would like the NTP update interval to be twice a day, so I will set the aforementioned CONFIG_LWIP_SNTP_UPDATE_DELAY somehow.
The whole ESP32 time.h and hal-time libraries are way over my head and I'll just have to take it on faith now that they do what they do somehow in their own cpu thread - the Espressif documentation on this would be a week's research for me to understand.
Any tips / suggestions are appreciated. Or, if this has been answered before and I somehow didn't find that after hours of Googling, just toss me a link. The seconds based loop concerns me - I obviously don't want to accidentally make repetitive NTP calls and get blacklisted lol.
Thanks!
EDIT - the 'getNTPtime(10);' in my loop concerns me because it seems to allow up to 10 seconds for it to process... That's fine for the initial synch, but afterwards it would be catastrophic for my one second loop to take 10 seconds to run...
EDIT2 - I've been Googling CONFIG_LWIP_SNTP_UPDATE_DELAY and it appears this is (was?) a compiler directive and could not be changed by the user in running code... I see references to this being revised (2019 discussion), but I'm uncertain if it has been and compiler directives like that are currently beyond my experience level anyway. I guess being 'stuck' with hourly updates isn't the worst thing...