Search code examples
esp32arduino-identp

Having ESP32 synchronized time for blinking LED using NTP sever


I would like to blink the ESP32 onboard LED (pin 2) every 5 seconds. I have set up a program that sets the time fro NTP sever. After loading the same code onto 3 different ESP32s, the LEDs blink every 5 seconds but are not at the same time. Is this a hardware issue or is my code incorrect? (also, is there a easier way to do this?). Thank you in advance!

#include <WiFi.h>
#include <TimeLib.h>

// Wifi Credentials
const char* ssid       = "OhanaAhimsa";
const char* password   = "Fam2021Wow!";

//NTP Sever initalization
const char* ntpServer = "pool.ntp.org";
const long  gmtOffset_sec = 3600;
const int   daylightOffset_sec = 3600;

// start now time variable in seconds
//int time_now = now();
//int second ();

void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(115200);

  // initialize digital pin LED_BUILTIN as an output.
  pinMode(2, OUTPUT);

// Connect to WiFi
  Serial.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
  }
  Serial.println(" CONNECTED");
  
  //init and get the time
 configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);

  struct tm timeinfo;
  if(!getLocalTime(&timeinfo)){
    Serial.println("Failed to obtain time");
    return;
  }

  //disconnect WiFi as it's no longer needed
  WiFi.disconnect(true);
  WiFi.mode(WIFI_OFF);
}
  
void loop() {

 // if (now() > time_now) {

    // Reset the time_now to now
  //  time_now = now();
    
    // print out seconds:
  // Serial.println(time_now);
   Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
    // Sets the LED on or off depending on time_now being pair or odd
    digitalWrite(2, second() % 5);
  }

void printLocalTime(){
  struct tm timeinfo;
  if(!getLocalTime(&timeinfo)){
    Serial.println("Failed to obtain time");
    return;
  }
  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
  Serial.print("Day of week: ");
  Serial.println(&timeinfo, "%A");
  Serial.print("Month: ");
  Serial.println(&timeinfo, "%B");
  Serial.print("Day of Month: ");
  Serial.println(&timeinfo, "%d");
  Serial.print("Year: ");
  Serial.println(&timeinfo, "%Y");
  Serial.print("Hour: ");
  Serial.println(&timeinfo, "%H");
  Serial.print("Hour (12 hour format): ");
  Serial.println(&timeinfo, "%I");
  Serial.print("Minute: ");
  Serial.println(&timeinfo, "%M");
  Serial.print("Second: ");
  Serial.println(&timeinfo, "%S");

  Serial.println("Time variables");
  char timeHour[3];
  strftime(timeHour,3, "%H", &timeinfo);
  Serial.println(timeHour);
  char timeWeekDay[10];
  strftime(timeWeekDay,10, "%A", &timeinfo);
  Serial.println(timeWeekDay);
  Serial.println();
}

Solution

  • you don't wait until time is retrieved from the NTP server and you don't set the time into the TimeLib.

    add

      time_t now = time(nullptr);
      while (now < SECS_YR_2000) { // wait until time is retrieved
        delay(100);
        now = time(nullptr);
      }
      setTime(now); // sets the time in TimeLib
    

    With setSyncProvider and setSyncInterval you can setup for TimeLib to sync with ESP32 RTC (which is set from NTP) periodically. See the examples of the TimeLib.