@@ -64,8 +64,9 @@ static time_t now;
6464static uint32_t now_ms, now_us;
6565
6666static esp8266::polledTimeout::periodicMs showTimeNow (60000 );
67- static int time_machine_days = 0 ; // 0 = now
67+ static int time_machine_days = 0 ; // 0 = present
6868static bool time_machine_running = false ;
69+ static bool time_machine_run_once = false ;
6970
7071// OPTIONAL: change SNTP startup delay
7172// a weak function is already defined and returns 0 (RFC violation)
@@ -112,7 +113,7 @@ void showTime() {
112113 // time from boot
113114 Serial.print (" clock: " );
114115 Serial.print ((uint32_t )tp.tv_sec );
115- Serial.print (" s / " );
116+ Serial.print (" s + " );
116117 Serial.print ((uint32_t )tp.tv_nsec );
117118 Serial.println (" ns" );
118119
@@ -125,7 +126,7 @@ void showTime() {
125126 // EPOCH+tz+dst
126127 Serial.print (" gtod: " );
127128 Serial.print ((uint32_t )tv.tv_sec );
128- Serial.print (" s / " );
129+ Serial.print (" s + " );
129130 Serial.print ((uint32_t )tv.tv_usec );
130131 Serial.println (" us" );
131132
@@ -140,7 +141,7 @@ void showTime() {
140141 Serial.print (" ctime: " );
141142 Serial.print (ctime (&now));
142143
143- // LwIP v2 is able to list more details about the currently configured SNTP servers
144+ // lwIP v2 is able to list more details about the currently configured SNTP servers
144145 for (int i = 0 ; i < SNTP_MAX_SERVERS; i++) {
145146 IPAddress sntp = *sntp_getserver (i);
146147 const char * name = sntp_getservername (i);
@@ -151,48 +152,67 @@ void showTime() {
151152 } else {
152153 Serial.printf (" %s " , sntp.toString ().c_str ());
153154 }
154- Serial.printf (" IPv6: %s Reachability: %o\n " ,
155+ Serial.printf (" - IPv6: %s - Reachability: %o\n " ,
155156 sntp.isV6 () ? " Yes" : " No" ,
156157 sntp_getreachability (i));
157158 }
158159 }
159160
160161 Serial.println ();
161162
162- // subsecond synchronisation
163- gettimeofday (&tv, nullptr );
164- time_t sec = tv.tv_sec ;
165- do {
163+ // show subsecond synchronisation
164+ timeval prevtv;
165+ time_t prevtime = time (nullptr );
166+ gettimeofday (&prevtv, nullptr );
167+
168+ while (true ) {
166169 gettimeofday (&tv, nullptr );
167- Serial.printf (" time(): %u gettimeofday(): %u.%06u" ,
168- (uint32_t )time (nullptr ),
169- (uint32_t )tv.tv_sec , (uint32_t )tv.tv_usec );
170- if (tv.tv_sec == sec) {
171- Serial.println (" second unchanged" );
172- } else {
173- Serial.println (" <-- second changed" );
170+ if (tv.tv_sec != prevtv.tv_sec ) {
171+ Serial.printf (" time(): %u gettimeofday(): %u.%06u seconds are unchanged\n " ,
172+ (uint32_t )prevtime,
173+ (uint32_t )prevtv.tv_sec , (uint32_t )prevtv.tv_usec );
174+ Serial.printf (" time(): %u gettimeofday(): %u.%06u <-- seconds have changed\n " ,
175+ (uint32_t )(prevtime = time (nullptr )),
176+ (uint32_t )tv.tv_sec , (uint32_t )tv.tv_usec );
177+ break ;
174178 }
179+ prevtv = tv;
175180 delay (50 );
176- } while (tv. tv_sec == sec);
181+ }
177182
178183 Serial.println ();
179184}
180185
181- void time_is_set_scheduled () {
182- // everything is allowed in this function
186+ void time_is_set (bool from_sntp /* <= this parameter is optional */ ) {
187+ // in CONT stack, unlike ISRs,
188+ // any function is allowed in this callback
183189
184190 if (time_machine_days == 0 ) {
185- time_machine_running = !time_machine_running;
191+ if (time_machine_running) {
192+ time_machine_run_once = true ;
193+ time_machine_running = false ;
194+ } else {
195+ time_machine_running = from_sntp && !time_machine_run_once;
196+ }
197+ if (time_machine_running) {
198+ Serial.printf (" \n -- \n -- Starting time machine demo to show libc's "
199+ " automatic DST handling\n -- \n " );
200+ }
201+ }
202+
203+ Serial.print (" settimeofday(" );
204+ if (from_sntp) {
205+ Serial.print (" SNTP" );
206+ } else {
207+ Serial.print (" USER" );
186208 }
209+ Serial.print (" )" );
187210
188211 // time machine demo
189212 if (time_machine_running) {
190- if (time_machine_days == 0 )
191- Serial.printf (" ---- settimeofday() has been called - possibly from SNTP\n "
192- " (starting time machine demo to show libc's automatic DST handling)\n\n " );
193213 now = time (nullptr );
194214 const tm* tm = localtime (&now);
195- Serial.printf (" future=%3ddays: DST=%s - " ,
215+ Serial.printf (" : future=%3ddays: DST=%s - " ,
196216 time_machine_days,
197217 tm->tm_isdst ? " true " : " false" );
198218 Serial.print (ctime (&now));
@@ -207,49 +227,55 @@ void time_is_set_scheduled() {
207227 }
208228 settimeofday (&tv, nullptr );
209229 } else {
210- showTime ();
230+ Serial. println ();
211231 }
212232}
213233
214234void setup () {
235+ WiFi.persistent (false );
236+ WiFi.mode (WIFI_OFF);
237+
215238 Serial.begin (115200 );
216- Serial.println (" \n Starting...\n " );
239+ Serial.println (" \n Starting in 2secs...\n " );
240+ delay (2000 );
241+
242+ // install callback - called when settimeofday is called (by SNTP or user)
243+ // once enabled (by DHCP), SNTP is updated every hour by default
244+ // ** optional boolean in callback function is true when triggerred by SNTP **
245+ settimeofday_cb (time_is_set);
217246
218247 // setup RTC time
219248 // it will be used until NTP server will send us real current time
249+ Serial.println (" Manually setting some time from some RTC:" );
220250 time_t rtc = RTC_UTC_TEST;
221251 timeval tv = { rtc, 0 };
222252 settimeofday (&tv, nullptr );
223253
224- // install callback - called when settimeofday is called (by SNTP or us)
225- // once enabled (by DHCP), SNTP is updated every hour
226- settimeofday_cb (time_is_set_scheduled);
227-
228254 // NTP servers may be overriden by your DHCP server for a more local one
229255 // (see below)
230256
231257 // ----> Here is the ONLY ONE LINE needed in your sketch
232-
233258 configTime (MYTZ, " pool.ntp.org" );
259+ // <----
260+ // Replace MYTZ by a value from TZ.h (search for this file in your filesystem).
234261
235- // Here is the ONLY ONE LINE needed in your sketch <----
236- // pick a value from TZ.h (search for this file in your filesystem) for MYTZ
237-
238- // former configTime is still valid, here is the call for 7 hours to the west
262+ // Former configTime is still valid, here is the call for 7 hours to the west
239263 // with an enabled 30mn DST
240264 // configTime(7 * 3600, 3600 / 2, "pool.ntp.org");
241265
242266 // OPTIONAL: disable obtaining SNTP servers from DHCP
243267 // sntp_servermode_dhcp(0); // 0: disable obtaining SNTP servers from DHCP (enabled by default)
244268
269+ // Give now a chance to the settimeofday callback,
270+ // because it is *always* deferred to the next yield()/loop()-call.
271+ yield ();
272+
245273 // start network
246- WiFi.persistent (false );
247274 WiFi.mode (WIFI_STA);
248275 WiFi.begin (STASSID, STAPSK);
249276
250277 // don't wait for network, observe time changing
251278 // when NTP timestamp is received
252- Serial.printf (" Time is currently set by a constant:\n " );
253279 showTime ();
254280}
255281
0 commit comments