Using NTP Server to set time - possible misunderstanding

Hi

I've been using calls to the NTP Server to set the time and date for ESP32 real-time projects. There are many posts with similar code to connect to the NTP server all following the basic format, of connecting to the local wifi, calling configTime( ), then calling getLocalTime( &timeInfo ), to get the time in the timeInfo structure. For example, see https://lastminuteengineers.com/esp32-ntp-server-date-time-tutorial/

This all works OK for me during setup, but then I noticed that having called configTime( ...) some examples then disconnect from the wifi, such as that given above. However, they then go on to claim that every time getLocalTime( &timeInfo ) is called, a request is sent to the NTP server. I don't understand how this is possible if the wifi has been disconnected. I suspect that there is a misunderstanding and subsequent calls to getLocalTime are actually recovering time based on the internal clock as accessed via millis( ) for example.

I think that to update the time from the NTP server, you would need to occasionally reconnect to the wifi and call configTime(...) again. I hope someone reading this can clarify, as there appears to be quite a few articles around which imply that the time is updated from the server every time getLocalTime(...) is called, including the one referenced.

For many projects running over short periods, the internal clock seems to be surprisingly accurate on the boards I'm using, but when you want accuracy over months of operation an occasional time update from the NTP server would be beneficial.

Thanks

Simon

Hello

When in doubt, look at the source code :slight_smile: arduino-esp32/esp32-hal-time.c at 99520f66f61d3c88014356ee96e1db89b1931ee4 · espressif/arduino-esp32 · GitHub

Thank you guix

If I've understood this correctly you are confirming that getTimeNow( ) is based on the local clock and uses millis( ), so the comment in the source I referenced is incorrect - it says:

getLocalTime() function is used to transmit a request packet to a NTP server and parse the received time stamp packet into to a readable format. It takes time structure as a parameter.

This is not the only place I've seen this, so beware! Can you confirm that calling configTime(...) when connected to wifi will update the local time?

All the best

Simon

The ESP32 is not using millis for counting time, but something similar

When configTime is called, it does an asynchronous NTP request, and when this request is finished, the result is stored as the system time

getLocalTime has an optional timeout parameter ms (with default value of 5 seconds), that is in case there is a NTP request being done in the background (for example when you just called configTime) so, if needed it will wait until the system time is "valid", and convert it to local time, or it will return false after this timeout duration if there is no "valid" system time yet ( it is considered valid when tm_year > (2016 - 1900) )

This link may help you undersand a few things : System Time - ESP32 - — ESP-IDF Programming Guide latest documentation

1 Like

The ESP32 has its own internal real time clock that can be set from a NTP server.

You can test it on your own:
a) set the NTP interval to 5 minutes
b) define a callback to see when NTP was synced
c) disconnect WIFI for > 5 minutes, you should not see the sync callback in that period
d) reconnect WIFI --> see how "fast" the ESP reacts on the re-established wifi connection. But latest after 5 minutes you should see again the sync messages.

On my page regarding ESP32 & NTP you find code snippets how to modify the interval and how to implement a sync callback.

1 Like

hi, i have a question regarding "set the NTP interval to 5 minutes". how can you do that? i undertood that you refer to internal RTC getting updated via NTP every 5 minutes. In a code that i'm working on, i'm able to sync for the first time but not periodically.
In IDF you can do that by setting a few parameters in the beggining of the code, then with a few conditions, it will sync the time automatically via NTP . In arduino i haven't found a way to do it without calling againg the NTP by hand, by touching a button or so.
how can i sync internal rtc when it shifts/drifts away from the current time via NTP(or every 1 day)? also i guess that you can get an event or a flag when it failed or succeded. Would like to know if it fails or not to show it with an LED.

Have you seen the page I 've posted? There is also a description how to include and use the function.

1 Like

Hi Juan, thank you for your message.

I think noiasca has made the point I was originally setting out to make, which is that functions to get the current time can only update from the NTP server if the wifi connection is made, otherwise the time/date returned is based on the internal clock. Follow the link to his page for more information. Some of the articles and code examples concerning the use of the NTP server are misleading as they show the initial setup and then disconnect from wifi but imply that subsequent calls are getting updates from the server – they are not if the wifi is disconnected. I suggest occasionally (once an hour or day) re-connecting wifi to ensure you get an update.

All the best,

Simon

1 Like

At the time no, now yes. i tried what you suggested on the page, i also noticed that in fact, the libraries are from IDF. i remembered using them on the same MCU but not with arduino, so it was easy to get on.
I am having a issue with the function sntp_set_sync_interval(). in some way, arduino isn't detecting the library where the function comes from, with the other functions if i can go to the definition of it. not with this one. the library "esp_sntp.h" is included properly. regarding to ntp / rtc i have included in my code the following libraries, maybe i am missing one where this function is declared. i am working on Arduino 2.0.0-rc9.2, esp32 1.0.6(latest), and libraries seem to be updated

#include <String.h>
#include <ESP32Time.h>
#include <WiFi.h>
#include <Adafruit_AHTX0.h>
#include <esp_log.h>
#include "esp_sntp.h"
#include "time.h"

then, inside setup(), i have this other subrutine to work out all about NTP.

esp_err_t initNTP(void){ // ntp time sync, it may have an error were it freezes code if wifi failed. yet to work with pointers.
  sntp_set_sync_mode(SNTP_SYNC_MODE_IMMED);
  sntp_set_time_sync_notification_cb(cbSyncTime);
  sntp_set_sync_interval(12 * 60 * 60 * 1000UL); // 12 hours, not working.
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  struct tm timeinfo;
  if (getLocalTime(&timeinfo)){
    rtc.setTimeStruct(timeinfo); 
  }
  return ESP_OK;
}

note that im using RTC and NTP, to have a backup in case wifi disconnects or something. the code sets RTC time via NTP, uses RTC time for some stuff(not inside the code provided) and my intention is to every x amount of time sync again automatically. the callback function is on another part of the code.

ERROR MESSAGE: 
(path)\functions.ino: In function 'esp_err_t initNTP()':
(path)\functions.ino:59:47: error: 'sntp_set_sync_interval' was not declared in this scope
   sntp_set_sync_interval(12 * 60 * 60 * 1000UL); // 12 hours

                                               ^

exit status 1

Compilation error: 'sntp_set_sync_interval' was not declared in this scope

thank you both for all the help, you've been very helpfull to me.
Juan Cruz

The OP may be looking at the documentation of the latest ESPRESSIFF IDE API release. Unfortunately, the Arduino ESP32 CORE does not use the latest ESPRESSIFF API. One may need to select one version down, in the ESPRESSIFF API documentation, to get the working version of the API the ESP32 Arduino core being used.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.