NTP Client - Incorrect Time

I need to read the PC time from an ESP8266.I have setup the PC as a NTP server & ESP8266 as NTP client. PC has connected to a non internet wifi router.

The problem is in below client code it starts from time 0.0.0 (Zero).Its not showing the PC time.

*Note - In this project there is no internet. I need to read the local PC time.

How to rectify it?

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <NTPClient.h>

// Replace with your network credentials
const char* ssid = "Link_Test";
const char* password = "123456";

// Replace with your PC's IP address or hostname running the NTP server
const char* ntpServerName = "192.168.1.2";

// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi...");
  }

  Serial.println("Connected to WiFi!");

  // Set NTP server address
  timeClient.setPoolServerName(ntpServerName);

  // Initialize NTP client
  timeClient.begin();
  timeClient.setTimeOffset(0);
  timeClient.forceUpdate();
}

void loop() {
  timeClient.update();

  // Print time obtained from the NTP server
  Serial.println(timeClient.getFormattedTime());

  delay(1000); // Wait for 1 second before updating the time again
}

You have to give the NTP-functions a little time to synchronise

/* Example Demo-Code for ESP8266 and ESP32
  Showing how to
  - organise code well structured into functions
  - connecting to a WiFi
  - synchronise time with an NTP-server
  - if connecting fails how to scan and print available WiFi-networks
  - how to use minuteOfDay and secondOfDay which make it easier to compare
  - the actual time with a certain point of time
  - a tricky way to use the serial monitor similar to a LC-Display
  - non-blocking timing based on function millis() with a helper-function
  - how to print a timestamp when the code was compiled
  written by user StefanL38
*/

#if defined(ESP32)
#include <WiFi.h>
char deviceType[] = "ESP32";
#else
#include <ESP8266WiFi.h>
char deviceType[] = "ESP8266";
#endif

unsigned long MyTestTimer = 0;                   // variables MUST be of type unsigned long
const byte    OnBoard_LED = 2;
int connectCounter = 0;
int NoOfWiFis;
long minuteOfDay;
long secondOfDay;

//const   char *ssid     = "your SSID";
//const char *password = "your password";

const char dayOfWeek[][16] = {"sunday",
                              "monday",
                              "tuesday",
                              "wednesday",
                              "thursday",
                              "friday",
                              "saturday"
                             };

// a lot of home-wlan-routers can be used as a NTP-server too
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
int Year;
int Month;
int Day;
int Hour;
int Minute;
int Second;
int DayIndex;


void updateMyTimeVars() {
 Year   = myTimeInfo.tm_year + 1900; // years since 1900
 Month  = myTimeInfo.tm_mon + 1;     // January = 0 (!)
 Day    = myTimeInfo.tm_mday;
 Hour   = myTimeInfo.tm_hour;
 Minute = myTimeInfo.tm_min;
 Second = myTimeInfo.tm_sec; 
 DayIndex = myTimeInfo.tm_wday;
}


void clearSerialMonitor() {
  for (int i = 0; i < 50; i++) {
    Serial.println();  // print 50 empty lines
  }
}


void showTime() {
  time(&now);                       // read the current time
  localtime_r(&now, &myTimeInfo);   // update the structure tm with the current time
  updateMyTimeVars();
    
  Serial.print("year:");
  Serial.print(Year);  

  Serial.print(" month:");
  if (Month < 10) {
    Serial.print("0");
  }
  Serial.print(Month);      

  Serial.print(" day:");
  if (Day < 10) {
    Serial.print("0");
  }
  Serial.print(Day);         // day of month

  Serial.print(" hour:");
  if (Hour < 10) {
    Serial.print("0");
  }
  Serial.print(Hour);         // hours since midnight  0-23

  Serial.print(" min:");
  if (Minute < 10) {
    Serial.print("0");
  }
  Serial.print(Minute);          // minutes after the hour  0-59

  Serial.print(" sec:");
  if (Second < 10) {
    Serial.print("0");
  }
  Serial.print(Second);          // seconds after the minute  0-61*
  Serial.print(" DayIndex:");

  Serial.print(DayIndex);         // days since Sunday 0-6

  Serial.print(" name of day ");
  Serial.print(dayOfWeek[DayIndex]);

  minuteOfDay = Hour *   60 + Minute;
  secondOfDay = Hour * 3600 + Minute * 60 + Second;
  Serial.println();
  Serial.println();

  Serial.print("minuteOfDay ");
  Serial.print(minuteOfDay);

  Serial.print(" secondOfDay ");
  Serial.print(secondOfDay);

  //                 12 hours    4 minutes  59 seconds = 12:04:59
  if (secondOfDay < (12 * 3600 + 4 * 60   + 59) ) {
    Serial.println(" actual time is before 12:04:59");
  }
  else {
    Serial.println(" actual time is AFTER 12:04:59");
  }
  Serial.println();
  Serial.println();
}


void connectToWifi() {
  Serial.print("try connecting to ");
  Serial.println(ssid);

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

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    yield(); // very important to have this function call to enable backround-processes
    BlinkHeartBeatLED(OnBoard_LED, 333);

    if ( TimePeriodIsOver(MyTestTimer, 500) ) {
      Serial.print(".");
      connectCounter++;
      if (connectCounter % 20 == 0) {
        Serial.println();
      }
    }

    if (connectCounter > 120) {
      break;
    }
  }

  if (WiFi.status() == WL_CONNECTED) {
    Serial.print("\n connected.");
    Serial.println(WiFi.localIP() );
  }
  else {
    Serial.print("\n unable to connect to WiFi with name #");
    Serial.print(ssid);
    Serial.println("#");
    ScanWiFis();
    Serial.print("\n code stopped with while(true) yield() ");
    while (true) {
      yield();
    }
  }
}

void ScanWiFis() {
  int WiFiIdx;

  Serial.println("Startscanning for networks");
  NoOfWiFis = WiFi.scanNetworks();
  Serial.println("scanning done List of SSIDs");
  Serial.print("found number of networks ");
  Serial.println(NoOfWiFis);

  for (WiFiIdx = 0; WiFiIdx < NoOfWiFis; WiFiIdx++) {
    // Print SSID and RSSI for each network found
    Serial.print(WiFiIdx);
    Serial.print(" #");
    Serial.print( String( WiFi.SSID(WiFiIdx) ) );
    Serial.print("# RSSI ");
    Serial.print( String (WiFi.RSSI(WiFiIdx)) );
    Serial.print(" dB");
    Serial.println();
  }
}


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);
  delay(2000);
  Serial.println("\n Setup-Start \n");
  PrintFileNameDateTime();

  connectToWifi();
  synchroniseWith_NTP_Time();
}

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

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

best regards Stefan

You mean to add some delays between time client functions? or wait 10 minutes after connecting to wifi?

as already shown - you should not use external libraries for NTP on an ESP8266 as the NTP functionality is already part of the ESP Core.

For usual the first NTP request will happen within 60 seconds using the core functions. But there is also a function sntp_startup_delay_MS_rfc_not_less_than_60000 that can be used to reduce that

You can read more about here:
https://werner.rothschopf.net/202011_arduino_esp8266_ntp_en.htm

just replace the at.pool.ntp.org hostname with your local PC name running as NTP Server (or your PC IP address).

1 Like

Very good reply. I'll use that.

I have another question. If there is two or three NTP servers on a PC, will that code read time from standard Microsoft time server? I mean if all three time servers runs together how the ESP decide from which one to get..!!

Thanks

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