ESP32 getting NTP time... and some odd behaviour

I am using an ESP32-CAM clone.

The project is to have a PIR sensor trigger video capture to SD card. The whole thing is battery powered so the intention is to have the ESP32 sleep until the PIR triggers, take the video then go back to sleep.

Everything works pretty well, except I noticed the timestamps on the files created were not set so I can't really tell when the files were created.

So, my plan was to set the ESP32's RTC time when everything is powered on. My problem is trying to set the time of the ESP32 RTC, via NTP, and specifically there are 2 weird things happening.

1). During Power On startup the time should be initialised, but if I omit the call to routine displayLocalTime in initialiseTime the the time does not seem to be set. The second call (in the setup routine) also fails.

If I leave the call in to displayLocalTime not only does that call succeed but so does the one in setup.

2). The other weird thing is that after sleeping, and being woke up from interrupt the time seems to have lost the timezone offset, as it is out by 13 hours.

Here is a cut down version of the troublesome code

#include <WiFi.h>                           
#include <ESP32Time.h>                      
 
ESP32Time rtc;

void setup()
{
  Serial.begin(115200);
  while(!Serial);
  
  esp_sleep_wakeup_cause_t wakeup_reason = esp_sleep_get_wakeup_cause();
  
  if (wakeup_reason == ESP_SLEEP_WAKEUP_EXT0)
    Serial.println("Wake up due to interupt");
  else
  {
    Serial.println("Power on startup");

    initialiseTime();
  }

  displayLocalTime();
    
  setInteruptAndSleep();
}



void loop(){}


void initialiseTime()
{
  const char *ssid               = "PK1";            // WiFi network to connect to.
  const char *password           = "******"; // Password. 
  const char *ntpServer          = "pool.ntp.org";   // NTP server.
  const long  gmtOffset_sec      = 46800;            // New Zealand GMT (+13 hours).
  const int   daylightOffset_sec = 3600;             // 1 hour daylight savings.
 
  Serial.print("Connecting to WiFi");
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println(" connected."); 

  
  Serial.println("Getting time.");

  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);

  //displayLocalTime();   // <<<< If this line present time is obtained.

  WiFi.disconnect(true);
  WiFi.mode(WIFI_OFF);
}


void displayLocalTime()
{
  struct tm timeinfo;
  
  if(getLocalTime(&timeinfo)) 
    Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
  else
    Serial.println("Failed to obtain time");
}


void setInteruptAndSleep()
{
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, 1);
  
  Serial.println("Going to sleep");
  delay(500);
  esp_deep_sleep_start();         
}

Here is the output if I omit the routine call from initialiseTime

Here is the output if I leave the call to in (note the time after starting from interrupt)

Not sure where I'm going wrong.., any help appreciated.

UPDATE:

The first problem seems to be related to the WiFi connection. If I move the call to displayLocalTime to after the connection is closed then it fails.


  WiFi.disconnect(true);
  WiFi.mode(WIFI_OFF);

  displayLocalTime();   // Fails when moved after connection closed.

Doesn't explain why the 2nd call works, if the first one does.

Bump...

Try following: don't set the time offset, but set the timezone.
Either follow the example in the IDE or try this example
https://werner.rothschopf.net/microcontroller/202103_arduino_esp32_ntp_en.htm

Going into and coming out of Deep Sleep is often frustrating to program. I have found this article to be a fair explanation of how to avoid common pitfalls:

https://www.mischianti.org/2021/03/18/esp32-practical-power-saving-store-data-timer-and-touch-wake-up-4/

Part 1 of the ESP32 Arduino tutorial

/*---------set with NTP---------------*/
//  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
//  struct tm timeinfo;
//  if (getLocalTime(&timeinfo)){
//    rtc.setTimeStruct(timeinfo);

Are you saying that configTime does not already set the RTC ?

If not, what does it do?

My guess is that it gets the time and
rtc.setTimeStruct(timeinfo)
saves it in the RTC.

... my understanding is that this is used if you want to set the time manually. If you use configTime it sets the RTC from the NTP time.

If you look at my examples the time is set.

This comes from the example on github from the guy who made the library.
https://github.com/fbiego/ESP32Time/blob/main/examples/esp32_time/esp32_time.ino

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