Save NTP time to RTC in ESP32

I noticed that when ESP32 is turned on, the time is displayed. About the internal RTC clock that the ESP32 has? Is it possible to continuously update this time using NTP? If so, does anyone have a code please? Next how to list RTC time.
Thank you very much for your help

This is one of the rare super-standard-examples I have a ready to use code for.
As long as the WLAN-connection is active the time is synchronised through the WLAN-connection

#include <WiFi.h>

unsigned long MyTestTimer = 0;                   // variables MUST be of type unsigned long
const byte    OnBoard_LED = 2;

//const char *ssid     = "WLANBuero_EXT"; 
const   char *ssid     = "FRITZ!Box 7490";

const char *password = "";

const char* ntpServer = "fritz.box";
const long  gmtOffset_sec = 0;
const int   daylightOffset_sec = 7200;

#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

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.println(ssid);

  WiFi.persistent(false);
  WiFi.mode(WIFI_STA);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    BlinkHeartBeatLED(OnBoard_LED, 333);
    delay(332);
    Serial.print(".");
  }
  Serial.print("\n connected.");
  Serial.println(WiFi.localIP() );

}

void synchroniseWith_NTP_Time() {
  Serial.print("configTime uses ntpServer ");
  Serial.println(ntpServer);
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  Serial.print("synchronising time");
  
  while (myTimeInfo.tm_year + 1900 < 2000 ) {
    time(&now);                       // read the current time
    localtime_r(&now, &myTimeInfo);
    BlinkHeartBeatLED(OnBoard_LED, 100);
    delay(100);
    Serial.print(".");
  }
  Serial.print("\n time synchronsized \n");
  showTime();    
}


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) ); 
  }
}


void setup() {
  Serial.begin(115200);
  Serial.println("\n Setup-Start \n");
  PrintFileNameDateTime();
  
  connectToWifi();
  synchroniseWith_NTP_Time();
}

void loop() {
  BlinkHeartBeatLED(OnBoard_LED,100);

  if ( TimePeriodIsOver(MyTestTimer,1000) ) {
    showTime();    
  }  
}

best regards Stefan

there is a NTP example in the IDE for the ESP32!

Nevertheless if you want to follow a smaller sketch, you might read my page
https://werner.rothschopf.net/microcontroller/202103_arduino_esp32_ntp_en.htm
it includes DST and explaines what happens.

thanks for the link werner - nice page; I'll try it now!

1 Like

How do I use a date into a string in the form HH: MM DD.MM.YYYY
Is it possible to list UNIX time? I.e. time in seconds since 1970?

The 'now' variable of datatype 'time_t' returned by the 'time(&now)' function is NTP Epoch Time (unsigned long seconds since Jan 1, 1900 I believe). It can be converted to Unix time.

How do I use a date into a string in the form HH: MM DD.MM.YYYY

Thank you very much for your help

localtime_r(&now, &myTimeInfo);

'myTimeInfo' is of type 'tm'. This is a struct. You can see its definition in time.h:

struct tm
{
  int	tm_sec;
  int	tm_min;
  int	tm_hour;
  int	tm_mday;
  int	tm_mon;
  int	tm_year;
  int	tm_wday;
  int	tm_yday;
  int	tm_isdst;
#ifdef __TM_GMTOFF
  long	__TM_GMTOFF;
#endif
#ifdef __TM_ZONE
  const char *__TM_ZONE;
#endif
};

Once you have the local time in a variable of type 'tm' you can use its members to format any type of string you want.

Actually, looking more closely at the source code, I see that the ESP32 version of <time.h> defines 'time_t' as a 'long'. So, it can't be referenced to NPT time epoch ( Jan 1, 1900). But, it is an epoch time and it shouldn't be too difficult for you to figure out the offset required to convert it to Unix time.

snprintf is your friend in building ANY data into a string.

I really do not know. I try it for several hours and I can't write the required time in the form HH: MM DD.MM.YYYY

I don't even know how to list UNIX time.

Will you please advise again? Very, very please.

// NTP TIME
long unsigned int epochTime;
struct tm timeinfo;
char buf[40];
strftime(buf, sizeof buf, "%H:%M %d-%m-%Y", &tm);
epochTime = buf;