From 0bb81a2d8106d5001e296562d5cb430e92dc930b Mon Sep 17 00:00:00 2001
From: gfvalvo <gfvalvo@gmail.com>
Date: Wed, 15 May 2019 22:19:36 -0400
Subject: [PATCH 1/2] Update for non-blocking SyncProvider function

---
 Time.cpp  | 253 ++++++++++++++++++++++++++++--------------------------
 TimeLib.h |  61 ++++++-------
 2 files changed, 163 insertions(+), 151 deletions(-)

diff --git a/Time.cpp b/Time.cpp
index 8e53e56..d3e7bcf 100644
--- a/Time.cpp
+++ b/Time.cpp
@@ -1,101 +1,101 @@
 /*
-  time.c - low level time and date functions
-  Copyright (c) Michael Margolis 2009-2014
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-  
-  1.0  6  Jan 2010 - initial release
-  1.1  12 Feb 2010 - fixed leap year calculation error
-  1.2  1  Nov 2010 - fixed setTime bug (thanks to Korman for this)
-  1.3  24 Mar 2012 - many edits by Paul Stoffregen: fixed timeStatus() to update
-                     status, updated examples for Arduino 1.0, fixed ARM
-                     compatibility issues, added TimeArduinoDue and TimeTeensy3
-                     examples, add error checking and messages to RTC examples,
-                     add examples to DS1307RTC library.
-  1.4  5  Sep 2014 - compatibility with Arduino 1.5.7
-*/
+ time.c - low level time and date functions
+ Copyright (c) Michael Margolis 2009-2014
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+ 1.0  6  Jan 2010 - initial release
+ 1.1  12 Feb 2010 - fixed leap year calculation error
+ 1.2  1  Nov 2010 - fixed setTime bug (thanks to Korman for this)
+ 1.3  24 Mar 2012 - many edits by Paul Stoffregen: fixed timeStatus() to update
+ status, updated examples for Arduino 1.0, fixed ARM
+ compatibility issues, added TimeArduinoDue and TimeTeensy3
+ examples, add error checking and messages to RTC examples,
+ add examples to DS1307RTC library.
+ 1.4  5  Sep 2014 - compatibility with Arduino 1.5.7
+ */
 
 #if ARDUINO >= 100
-#include <Arduino.h> 
+#include <Arduino.h>
 #else
-#include <WProgram.h> 
+#include <WProgram.h>
 #endif
 
 #include "TimeLib.h"
 
 static tmElements_t tm;          // a cache of time elements
 static time_t cacheTime;   // the time the cache was updated
-static uint32_t syncInterval = 300;  // time sync will be attempted after this many seconds
+static uint32_t syncInterval = 300; // time sync will be attempted after this many seconds
 
 void refreshCache(time_t t) {
   if (t != cacheTime) {
-    breakTime(t, tm); 
-    cacheTime = t; 
+    breakTime(t, tm);
+    cacheTime = t;
   }
 }
 
-int hour() { // the hour now 
-  return hour(now()); 
+int hour() { // the hour now
+  return hour(now());
 }
 
 int hour(time_t t) { // the hour for the given time
   refreshCache(t);
-  return tm.Hour;  
+  return tm.Hour;
 }
 
 int hourFormat12() { // the hour now in 12 hour format
-  return hourFormat12(now()); 
+  return hourFormat12(now());
 }
 
 int hourFormat12(time_t t) { // the hour for the given time in 12 hour format
   refreshCache(t);
-  if( tm.Hour == 0 )
+  if (tm.Hour == 0)
     return 12; // 12 midnight
-  else if( tm.Hour  > 12)
-    return tm.Hour - 12 ;
+  else if (tm.Hour > 12)
+    return tm.Hour - 12;
   else
-    return tm.Hour ;
+    return tm.Hour;
 }
 
 uint8_t isAM() { // returns true if time now is AM
-  return !isPM(now()); 
+  return !isPM(now());
 }
 
 uint8_t isAM(time_t t) { // returns true if given time is AM
-  return !isPM(t);  
+  return !isPM(t);
 }
 
 uint8_t isPM() { // returns true if PM
-  return isPM(now()); 
+  return isPM(now());
 }
 
 uint8_t isPM(time_t t) { // returns true if PM
-  return (hour(t) >= 12); 
+  return (hour(t) >= 12);
 }
 
 int minute() {
-  return minute(now()); 
+  return minute(now());
 }
 
 int minute(time_t t) { // the minute for the given time
   refreshCache(t);
-  return tm.Minute;  
+  return tm.Minute;
 }
 
 int second() {
-  return second(now()); 
+  return second(now());
 }
 
 int second(time_t t) {  // the second for the given time
@@ -103,8 +103,8 @@ int second(time_t t) {  // the second for the given time
   return tm.Second;
 }
 
-int day(){
-  return(day(now())); 
+int day() {
+  return (day(now()));
 }
 
 int day(time_t t) { // the day for the given time (0-6)
@@ -113,16 +113,16 @@ int day(time_t t) { // the day for the given time (0-6)
 }
 
 int weekday() {   // Sunday is day 1
-  return  weekday(now()); 
+  return weekday(now());
 }
 
 int weekday(time_t t) {
   refreshCache(t);
   return tm.Wday;
 }
-   
-int month(){
-  return month(now()); 
+
+int month() {
+  return month(now());
 }
 
 int month(time_t t) {  // the month for the given time
@@ -130,8 +130,8 @@ int month(time_t t) {  // the month for the given time
   return tm.Month;
 }
 
-int year() {  // as in Processing, the full four digit year: (2009, 2010 etc) 
-  return year(now()); 
+int year() {  // as in Processing, the full four digit year: (2009, 2010 etc)
+  return year(now());
 }
 
 int year(time_t t) { // the year for the given time
@@ -139,16 +139,17 @@ int year(time_t t) { // the year for the given time
   return tmYearToCalendar(tm.Year);
 }
 
-/*============================================================================*/	
+/*============================================================================*/
 /* functions to convert to and from system time */
 /* These are for interfacing with time serivces and are not normally needed in a sketch */
 
 // leap year calulator expects year argument as years offset from 1970
 #define LEAP_YEAR(Y)     ( ((1970+(Y))>0) && !((1970+(Y))%4) && ( ((1970+(Y))%100) || !((1970+(Y))%400) ) )
 
-static  const uint8_t monthDays[]={31,28,31,30,31,30,31,31,30,31,30,31}; // API starts months from 1, this array starts from 0
- 
-void breakTime(time_t timeInput, tmElements_t &tm){
+static const uint8_t monthDays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30,
+    31 }; // API starts months from 1, this array starts from 0
+
+void breakTime(time_t timeInput, tmElements_t &tm) {
 // break the given time_t into time components
 // this is a more compact version of the C library localtime function
 // note that year is offset from 1970 !!!
@@ -158,103 +159,103 @@ void breakTime(time_t timeInput, tmElements_t &tm){
   uint32_t time;
   unsigned long days;
 
-  time = (uint32_t)timeInput;
+  time = (uint32_t) timeInput;
   tm.Second = time % 60;
   time /= 60; // now it is minutes
   tm.Minute = time % 60;
   time /= 60; // now it is hours
   tm.Hour = time % 24;
   time /= 24; // now it is days
-  tm.Wday = ((time + 4) % 7) + 1;  // Sunday is day 1 
-  
-  year = 0;  
+  tm.Wday = ((time + 4) % 7) + 1;  // Sunday is day 1
+
+  year = 0;
   days = 0;
-  while((unsigned)(days += (LEAP_YEAR(year) ? 366 : 365)) <= time) {
+  while ((unsigned) (days += (LEAP_YEAR(year) ? 366 : 365)) <= time) {
     year++;
   }
-  tm.Year = year; // year is offset from 1970 
-  
+  tm.Year = year; // year is offset from 1970
+
   days -= LEAP_YEAR(year) ? 366 : 365;
-  time  -= days; // now it is days in this year, starting at 0
-  
-  days=0;
-  month=0;
-  monthLength=0;
-  for (month=0; month<12; month++) {
-    if (month==1) { // february
+  time -= days; // now it is days in this year, starting at 0
+
+  days = 0;
+  month = 0;
+  monthLength = 0;
+  for (month = 0; month < 12; month++) {
+    if (month == 1) { // february
       if (LEAP_YEAR(year)) {
-        monthLength=29;
+        monthLength = 29;
       } else {
-        monthLength=28;
+        monthLength = 28;
       }
     } else {
       monthLength = monthDays[month];
     }
-    
+
     if (time >= monthLength) {
       time -= monthLength;
     } else {
-        break;
+      break;
     }
   }
-  tm.Month = month + 1;  // jan is month 1  
+  tm.Month = month + 1;  // jan is month 1
   tm.Day = time + 1;     // day of month
 }
 
-time_t makeTime(const tmElements_t &tm){   
-// assemble time elements into time_t 
+time_t makeTime(const tmElements_t &tm) {
+// assemble time elements into time_t
 // note year argument is offset from 1970 (see macros in time.h to convert to other formats)
 // previous version used full four digit year (or digits since 2000),i.e. 2009 was 2009 or 9
-  
+
   int i;
   uint32_t seconds;
 
   // seconds from 1970 till 1 jan 00:00:00 of the given year
-  seconds= tm.Year*(SECS_PER_DAY * 365);
+  seconds = tm.Year * (SECS_PER_DAY * 365);
   for (i = 0; i < tm.Year; i++) {
     if (LEAP_YEAR(i)) {
-      seconds +=  SECS_PER_DAY;   // add extra days for leap years
+      seconds += SECS_PER_DAY;   // add extra days for leap years
     }
   }
-  
+
   // add days for this year, months start from 1
   for (i = 1; i < tm.Month; i++) {
-    if ( (i == 2) && LEAP_YEAR(tm.Year)) { 
+    if ((i == 2) && LEAP_YEAR(tm.Year)) {
       seconds += SECS_PER_DAY * 29;
     } else {
-      seconds += SECS_PER_DAY * monthDays[i-1];  //monthDay array starts from 0
+      seconds += SECS_PER_DAY * monthDays[i - 1]; //monthDay array starts from 0
     }
   }
-  seconds+= (tm.Day-1) * SECS_PER_DAY;
-  seconds+= tm.Hour * SECS_PER_HOUR;
-  seconds+= tm.Minute * SECS_PER_MIN;
-  seconds+= tm.Second;
-  return (time_t)seconds; 
+  seconds += (tm.Day - 1) * SECS_PER_DAY;
+  seconds += tm.Hour * SECS_PER_HOUR;
+  seconds += tm.Minute * SECS_PER_MIN;
+  seconds += tm.Second;
+  return (time_t) seconds;
 }
-/*=====================================================*/	
+/*=====================================================*/
 /* Low level system time functions  */
 
 static uint32_t sysTime = 0;
 static uint32_t prevMillis = 0;
 static uint32_t nextSyncTime = 0;
 static timeStatus_t Status = timeNotSet;
+static bool immediateRetry = false;
 
 getExternalTime getTimePtr;  // pointer to external sync function
 //setExternalTime setTimePtr; // not used in this version
 
 #ifdef TIME_DRIFT_INFO   // define this to get drift data
-time_t sysUnsyncedTime = 0; // the time sysTime unadjusted by sync  
+time_t sysUnsyncedTime = 0; // the time sysTime unadjusted by sync
 #endif
 
-
 time_t now() {
-	// calculate number of seconds passed since last call to now()
+  // calculate number of seconds passed since last call to now()
   while (millis() - prevMillis >= 1000) {
-		// millis() and prevMillis are both unsigned ints thus the subtraction will always be the absolute value of the difference
+    // millis() and prevMillis are both unsigned ints thus the subtraction will always be the absolute value of the difference
     sysTime++;
-    prevMillis += 1000;	
+    prevMillis += 1000;
 #ifdef TIME_DRIFT_INFO
-    sysUnsyncedTime++; // this can be compared to the synced time to measure long term drift     
+    sysUnsyncedTime++; // this can be compared to the synced time to measure long term drift
 #endif
   }
   if (nextSyncTime <= sysTime) {
@@ -263,33 +264,35 @@ time_t now() {
       if (t != 0) {
         setTime(t);
       } else {
-        nextSyncTime = sysTime + syncInterval;
-        Status = (Status == timeNotSet) ?  timeNotSet : timeNeedsSync;
+        if (!immediateRetry) {
+          nextSyncTime = sysTime + syncInterval;
+        }
+        Status = (Status == timeNotSet) ? timeNotSet : timeNeedsSync;
       }
     }
-  }  
-  return (time_t)sysTime;
+  }
+  return (time_t) sysTime;
 }
 
-void setTime(time_t t) { 
+void setTime(time_t t) {
 #ifdef TIME_DRIFT_INFO
- if(sysUnsyncedTime == 0) 
-   sysUnsyncedTime = t;   // store the time of the first call to set a valid Time   
+  if(sysUnsyncedTime == 0)
+  sysUnsyncedTime = t;   // store the time of the first call to set a valid Time
 #endif
 
-  sysTime = (uint32_t)t;  
-  nextSyncTime = (uint32_t)t + syncInterval;
+  sysTime = (uint32_t) t;
+  nextSyncTime = (uint32_t) t + syncInterval;
   Status = timeSet;
-  prevMillis = millis();  // restart counting from now (thanks to Korman for this fix)
-} 
-
-void setTime(int hr,int min,int sec,int dy, int mnth, int yr){
- // year can be given as full four digit year or two digts (2010 or 10 for 2010);  
- //it is converted to years since 1970
-  if( yr > 99)
-      yr = yr - 1970;
+  prevMillis = millis(); // restart counting from now (thanks to Korman for this fix)
+}
+
+void setTime(int hr, int min, int sec, int dy, int mnth, int yr) {
+  // year can be given as full four digit year or two digts (2010 or 10 for 2010);
+  //it is converted to years since 1970
+  if (yr > 99)
+    yr = yr - 1970;
   else
-      yr += 30;  
+    yr += 30;
   tm.Year = yr;
   tm.Month = mnth;
   tm.Day = dy;
@@ -309,13 +312,21 @@ timeStatus_t timeStatus() {
   return Status;
 }
 
-void setSyncProvider( getExternalTime getTimeFunction){
-  getTimePtr = getTimeFunction;  
+void setSyncProvider(getExternalTime getTimeFunction, bool immedRetry,
+bool wait) {
+  getTimePtr = getTimeFunction;
   nextSyncTime = sysTime;
-  now(); // this will sync the clock
+  immediateRetry = immedRetry;
+  while (Status != timeSet) {
+    now(); // this will sync the clock
+    if (!wait) {
+      break;
+    }
+    delay(1);
+  }
 }
 
-void setSyncInterval(time_t interval){ // set the number of seconds between re-sync
-  syncInterval = (uint32_t)interval;
+void setSyncInterval(time_t interval) { // set the number of seconds between re-sync
+  syncInterval = (uint32_t) interval;
   nextSyncTime = sysTime + syncInterval;
 }
diff --git a/TimeLib.h b/TimeLib.h
index 20e2445..d5915d9 100644
--- a/TimeLib.h
+++ b/TimeLib.h
@@ -5,7 +5,7 @@
 /*
   July 3 2011 - fixed elapsedSecsThisWeek macro (thanks Vincent Valdy for this)
               - fixed  daysToTime_t macro (thanks maniacbug)
-*/     
+*/
 
 #ifndef _Time_h
 #ifdef __cplusplus
@@ -40,23 +40,23 @@ typedef enum {
 
 typedef enum {
     tmSecond, tmMinute, tmHour, tmWday, tmDay,tmMonth, tmYear, tmNbrFields
-} tmByteFields;	   
+} tmByteFields;
 
-typedef struct  { 
-  uint8_t Second; 
-  uint8_t Minute; 
-  uint8_t Hour; 
+typedef struct  {
+  uint8_t Second;
+  uint8_t Minute;
+  uint8_t Hour;
   uint8_t Wday;   // day of week, sunday is day 1
   uint8_t Day;
-  uint8_t Month; 
-  uint8_t Year;   // offset from 1970; 
+  uint8_t Month;
+  uint8_t Year;   // offset from 1970;
 } 	tmElements_t, TimeElements, *tmElementsPtr_t;
 
-//convenience macros to convert to and from tm years 
-#define  tmYearToCalendar(Y) ((Y) + 1970)  // full four digit year 
+//convenience macros to convert to and from tm years
+#define  tmYearToCalendar(Y) ((Y) + 1970)  // full four digit year
 #define  CalendarYrToTm(Y)   ((Y) - 1970)
 #define  tmYearToY2k(Y)      ((Y) - 30)    // offset is from 2000
-#define  y2kYearToTm(Y)      ((Y) + 30)   
+#define  y2kYearToTm(Y)      ((Y) + 30)
 
 typedef time_t(*getExternalTime)();
 //typedef void  (*setExternalTime)(const time_t); // not used in this version
@@ -71,32 +71,32 @@ typedef time_t(*getExternalTime)();
 #define SECS_PER_WEEK ((time_t)(SECS_PER_DAY * DAYS_PER_WEEK))
 #define SECS_PER_YEAR ((time_t)(SECS_PER_DAY * 365UL)) // TODO: ought to handle leap years
 #define SECS_YR_2000  ((time_t)(946684800UL)) // the time at the start of y2k
- 
+
 /* Useful Macros for getting elapsed time */
-#define numberOfSeconds(_time_) ((_time_) % SECS_PER_MIN)  
-#define numberOfMinutes(_time_) (((_time_) / SECS_PER_MIN) % SECS_PER_MIN) 
+#define numberOfSeconds(_time_) ((_time_) % SECS_PER_MIN)
+#define numberOfMinutes(_time_) (((_time_) / SECS_PER_MIN) % SECS_PER_MIN)
 #define numberOfHours(_time_) (((_time_) % SECS_PER_DAY) / SECS_PER_HOUR)
 #define dayOfWeek(_time_) ((((_time_) / SECS_PER_DAY + 4)  % DAYS_PER_WEEK)+1) // 1 = Sunday
 #define elapsedDays(_time_) ((_time_) / SECS_PER_DAY)  // this is number of days since Jan 1 1970
-#define elapsedSecsToday(_time_) ((_time_) % SECS_PER_DAY)   // the number of seconds since last midnight 
+#define elapsedSecsToday(_time_) ((_time_) % SECS_PER_DAY)   // the number of seconds since last midnight
 // The following macros are used in calculating alarms and assume the clock is set to a date later than Jan 1 1971
 // Always set the correct time before settting alarms
 #define previousMidnight(_time_) (((_time_) / SECS_PER_DAY) * SECS_PER_DAY)  // time at the start of the given day
-#define nextMidnight(_time_) (previousMidnight(_time_)  + SECS_PER_DAY)   // time at the end of the given day 
+#define nextMidnight(_time_) (previousMidnight(_time_)  + SECS_PER_DAY)   // time at the end of the given day
 #define elapsedSecsThisWeek(_time_) (elapsedSecsToday(_time_) +  ((dayOfWeek(_time_)-1) * SECS_PER_DAY))   // note that week starts on day 1
 #define previousSunday(_time_) ((_time_) - elapsedSecsThisWeek(_time_))      // time at the start of the week for the given time
 #define nextSunday(_time_) (previousSunday(_time_)+SECS_PER_WEEK)          // time at the end of the week for the given time
 
 
 /* Useful Macros for converting elapsed time to a time_t */
-#define minutesToTime_t ((M)) ( (M) * SECS_PER_MIN)  
-#define hoursToTime_t   ((H)) ( (H) * SECS_PER_HOUR)  
+#define minutesToTime_t ((M)) ( (M) * SECS_PER_MIN)
+#define hoursToTime_t   ((H)) ( (H) * SECS_PER_HOUR)
 #define daysToTime_t    ((D)) ( (D) * SECS_PER_DAY) // fixed on Jul 22 2011
-#define weeksToTime_t   ((W)) ( (W) * SECS_PER_WEEK)   
+#define weeksToTime_t   ((W)) ( (W) * SECS_PER_WEEK)
 
 /*============================================================================*/
 /*  time and date functions   */
-int     hour();            // the hour now 
+int     hour();            // the hour now
 int     hour(time_t t);    // the hour for the given time
 int     hourFormat12();    // the hour now in 12 hour format
 int     hourFormat12(time_t t); // the hour for the given time in 12 hour format
@@ -104,34 +104,35 @@ uint8_t isAM();            // returns true if time now is AM
 uint8_t isAM(time_t t);    // returns true the given time is AM
 uint8_t isPM();            // returns true if time now is PM
 uint8_t isPM(time_t t);    // returns true the given time is PM
-int     minute();          // the minute now 
+int     minute();          // the minute now
 int     minute(time_t t);  // the minute for the given time
-int     second();          // the second now 
+int     second();          // the second now
 int     second(time_t t);  // the second for the given time
-int     day();             // the day now 
+int     day();             // the day now
 int     day(time_t t);     // the day for the given time
-int     weekday();         // the weekday now (Sunday is day 1) 
-int     weekday(time_t t); // the weekday for the given time 
+int     weekday();         // the weekday now (Sunday is day 1)
+int     weekday(time_t t); // the weekday for the given time
 int     month();           // the month now  (Jan is month 1)
 int     month(time_t t);   // the month for the given time
-int     year();            // the full four digit year: (2009, 2010 etc) 
+int     year();            // the full four digit year: (2009, 2010 etc)
 int     year(time_t t);    // the year for the given time
 
-time_t now();              // return the current time as seconds since Jan 1 1970 
+time_t now();              // return the current time as seconds since Jan 1 1970
 void    setTime(time_t t);
 void    setTime(int hr,int min,int sec,int day, int month, int yr);
 void    adjustTime(long adjustment);
 
-/* date strings */ 
+/* date strings */
 #define dt_MAX_STRING_LEN 9 // length of longest date string (excluding terminating null)
 char* monthStr(uint8_t month);
 char* dayStr(uint8_t day);
 char* monthShortStr(uint8_t month);
 char* dayShortStr(uint8_t day);
-	
+
 /* time sync functions	*/
 timeStatus_t timeStatus(); // indicates if time has been set and recently synchronized
-void    setSyncProvider( getExternalTime getTimeFunction); // identify the external time provider
+void setSyncProvider(getExternalTime getTimeFunction, bool immedRetry = false,
+    bool wait = false); // identify the external time provider
 void    setSyncInterval(time_t interval); // set the number of seconds between re-sync
 
 /* low level functions to convert to and from system time                     */

From c65723d601f1a75b98a9ecd76268399a5b073890 Mon Sep 17 00:00:00 2001
From: gfvalvo <gfvalvo@gmail.com>
Date: Wed, 15 May 2019 22:19:55 -0400
Subject: [PATCH 2/2] Update for non-blocking SyncProvider function

---
 .../TimeNTP_ESP8266WiFi.ino                   | 235 +++++++++---------
 1 file changed, 122 insertions(+), 113 deletions(-)

diff --git a/examples/TimeNTP_ESP8266WiFi/TimeNTP_ESP8266WiFi.ino b/examples/TimeNTP_ESP8266WiFi/TimeNTP_ESP8266WiFi.ino
index 1aeb2d7..ed837fd 100644
--- a/examples/TimeNTP_ESP8266WiFi/TimeNTP_ESP8266WiFi.ino
+++ b/examples/TimeNTP_ESP8266WiFi/TimeNTP_ESP8266WiFi.ino
@@ -1,16 +1,17 @@
-/*
- * TimeNTP_ESP8266WiFi.ino
- * Example showing time sync to NTP time source
- *
- * This sketch uses the ESP8266WiFi library
- */
-
-#include <TimeLib.h>
+#include "Arduino.h"
+#include "TimeLib.h"
 #include <ESP8266WiFi.h>
 #include <WiFiUdp.h>
 
-const char ssid[] = "*************";  //  your network SSID (name)
-const char pass[] = "********";       // your network password
+/*
+ TimeNTP_ESP8266WiFi.ino
+ Example showing time sync to NTP time source
+
+ This sketch uses the ESP8266WiFi library
+ */
+
+//const char ssid[] = "*************";  //  your network SSID (name)
+//const char pass[] = "********";       // your network password
 
 // NTP Servers:
 static const char ntpServerName[] = "us.pool.ntp.org";
@@ -25,7 +26,6 @@ const int timeZone = 1;     // Central European Time
 //const int timeZone = -8;  // Pacific Standard Time (USA)
 //const int timeZone = -7;  // Pacific Daylight Time (USA)
 
-
 WiFiUDP Udp;
 unsigned int localPort = 8888;  // local port to listen for UDP packets
 
@@ -34,66 +34,63 @@ void digitalClockDisplay();
 void printDigits(int digits);
 void sendNTPpacket(IPAddress &address);
 
-void setup()
-{
-  Serial.begin(9600);
-  while (!Serial) ; // Needed for Leonardo only
-  delay(250);
-  Serial.println("TimeNTP Example");
-  Serial.print("Connecting to ");
-  Serial.println(ssid);
-  WiFi.begin(ssid, pass);
-
-  while (WiFi.status() != WL_CONNECTED) {
-    delay(500);
-    Serial.print(".");
-  }
-
-  Serial.print("IP number assigned by DHCP is ");
-  Serial.println(WiFi.localIP());
-  Serial.println("Starting UDP");
-  Udp.begin(localPort);
-  Serial.print("Local port: ");
-  Serial.println(Udp.localPort());
-  Serial.println("waiting for sync");
-  setSyncProvider(getNtpTime);
-  setSyncInterval(300);
+void setup() {
+	Serial.begin(115200);
+	while (!Serial)
+		; // Needed for Leonardo only
+	delay(250);
+	Serial.println("TimeNTP Example");
+	Serial.print("Connecting to ");
+	Serial.println(ssid);
+	WiFi.begin(ssid, pass);
+
+	while (WiFi.status() != WL_CONNECTED) {
+		delay(500);
+		Serial.print(".");
+	}
+
+	Serial.print("IP number assigned by DHCP is ");
+	Serial.println(WiFi.localIP());
+	Serial.println("Starting UDP");
+	Udp.begin(localPort);
+	Serial.print("Local port: ");
+	Serial.println(Udp.localPort());
+	Serial.println("waiting for sync");
+	setSyncProvider(getNtpTime, true, true);
+	setSyncInterval(300);
 }
 
 time_t prevDisplay = 0; // when the digital clock was displayed
 
-void loop()
-{
-  if (timeStatus() != timeNotSet) {
-    if (now() != prevDisplay) { //update the display only if time has changed
-      prevDisplay = now();
-      digitalClockDisplay();
-    }
-  }
+void loop() {
+	if (timeStatus() != timeNotSet) {
+		if (now() != prevDisplay) { //update the display only if time has changed
+			prevDisplay = now();
+			digitalClockDisplay();
+		}
+	}
 }
 
-void digitalClockDisplay()
-{
-  // digital clock display of the time
-  Serial.print(hour());
-  printDigits(minute());
-  printDigits(second());
-  Serial.print(" ");
-  Serial.print(day());
-  Serial.print(".");
-  Serial.print(month());
-  Serial.print(".");
-  Serial.print(year());
-  Serial.println();
+void digitalClockDisplay() {
+	// digital clock display of the time
+	Serial.print(hour());
+	printDigits(minute());
+	printDigits(second());
+	Serial.print(" ");
+	Serial.print(day());
+	Serial.print(".");
+	Serial.print(month());
+	Serial.print(".");
+	Serial.print(year());
+	Serial.println();
 }
 
-void printDigits(int digits)
-{
-  // utility for digital clock display: prints preceding colon and leading 0
-  Serial.print(":");
-  if (digits < 10)
-    Serial.print('0');
-  Serial.print(digits);
+void printDigits(int digits) {
+	// utility for digital clock display: prints preceding colon and leading 0
+	Serial.print(":");
+	if (digits < 10)
+		Serial.print('0');
+	Serial.print(digits);
 }
 
 /*-------- NTP code ----------*/
@@ -101,56 +98,68 @@ void printDigits(int digits)
 const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
 byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets
 
-time_t getNtpTime()
-{
-  IPAddress ntpServerIP; // NTP server's ip address
-
-  while (Udp.parsePacket() > 0) ; // discard any previously received packets
-  Serial.println("Transmit NTP Request");
-  // get a random server from the pool
-  WiFi.hostByName(ntpServerName, ntpServerIP);
-  Serial.print(ntpServerName);
-  Serial.print(": ");
-  Serial.println(ntpServerIP);
-  sendNTPpacket(ntpServerIP);
-  uint32_t beginWait = millis();
-  while (millis() - beginWait < 1500) {
-    int size = Udp.parsePacket();
-    if (size >= NTP_PACKET_SIZE) {
-      Serial.println("Receive NTP Response");
-      Udp.read(packetBuffer, NTP_PACKET_SIZE);  // read packet into the buffer
-      unsigned long secsSince1900;
-      // convert four bytes starting at location 40 to a long integer
-      secsSince1900 =  (unsigned long)packetBuffer[40] << 24;
-      secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
-      secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
-      secsSince1900 |= (unsigned long)packetBuffer[43];
-      return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
-    }
-  }
-  Serial.println("No NTP Response :-(");
-  return 0; // return 0 if unable to get the time
+time_t getNtpTime() {
+	IPAddress ntpServerIP; // NTP server's ip address
+	static bool waitingResponse = false;
+	static uint32_t packetSendTime;
+	const uint32_t maxWaitTime = 1500;
+
+	if (!waitingResponse) {
+		while (Udp.parsePacket() > 0)
+			; // discard any previously received packets
+		Serial.println("Transmit NTP Request");
+		// get a random server from the pool
+		WiFi.hostByName(ntpServerName, ntpServerIP);
+		Serial.print(ntpServerName);
+		Serial.print(": ");
+		Serial.println(ntpServerIP);
+		sendNTPpacket(ntpServerIP);
+		waitingResponse = true;
+		packetSendTime = millis();
+		return 0;
+	}
+
+	int size = Udp.parsePacket();
+	if (size >= NTP_PACKET_SIZE) {
+		Serial.print("Receive NTP Response, Delay = ");
+		Serial.print(millis() - packetSendTime);
+		Serial.println(" ms");
+		Udp.read(packetBuffer, NTP_PACKET_SIZE);  // read packet into the buffer
+		unsigned long secsSince1900;
+		// convert four bytes starting at location 40 to a long integer
+		secsSince1900 = (unsigned long) packetBuffer[40] << 24;
+		secsSince1900 |= (unsigned long) packetBuffer[41] << 16;
+		secsSince1900 |= (unsigned long) packetBuffer[42] << 8;
+		secsSince1900 |= (unsigned long) packetBuffer[43];
+		waitingResponse = false;
+		return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
+	}
+
+	if (millis() - packetSendTime >= maxWaitTime) {
+		waitingResponse = false;
+		Serial.println("NTP Request Timed Out");
+	}
+	return 0;
 }
 
 // send an NTP request to the time server at the given address
-void sendNTPpacket(IPAddress &address)
-{
-  // set all bytes in the buffer to 0
-  memset(packetBuffer, 0, NTP_PACKET_SIZE);
-  // Initialize values needed to form NTP request
-  // (see URL above for details on the packets)
-  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
-  packetBuffer[1] = 0;     // Stratum, or type of clock
-  packetBuffer[2] = 6;     // Polling Interval
-  packetBuffer[3] = 0xEC;  // Peer Clock Precision
-  // 8 bytes of zero for Root Delay & Root Dispersion
-  packetBuffer[12] = 49;
-  packetBuffer[13] = 0x4E;
-  packetBuffer[14] = 49;
-  packetBuffer[15] = 52;
-  // all NTP fields have been given values, now
-  // you can send a packet requesting a timestamp:
-  Udp.beginPacket(address, 123); //NTP requests are to port 123
-  Udp.write(packetBuffer, NTP_PACKET_SIZE);
-  Udp.endPacket();
-}
+void sendNTPpacket(IPAddress &address) {
+	// set all bytes in the buffer to 0
+	memset(packetBuffer, 0, NTP_PACKET_SIZE);
+	// Initialize values needed to form NTP request
+	// (see URL above for details on the packets)
+	packetBuffer[0] = 0b11100011;   // LI, Version, Mode
+	packetBuffer[1] = 0;     // Stratum, or type of clock
+	packetBuffer[2] = 6;     // Polling Interval
+	packetBuffer[3] = 0xEC;  // Peer Clock Precision
+	// 8 bytes of zero for Root Delay & Root Dispersion
+	packetBuffer[12] = 49;
+	packetBuffer[13] = 0x4E;
+	packetBuffer[14] = 49;
+	packetBuffer[15] = 52;
+	// all NTP fields have been given values, now
+	// you can send a packet requesting a timestamp:
+	Udp.beginPacket(address, 123); //NTP requests are to port 123
+	Udp.write(packetBuffer, NTP_PACKET_SIZE);
+	Udp.endPacket();
+}