@@ -81,95 +81,67 @@ void NTPClient::begin(unsigned int port) {
81
81
this ->_udpSetup = true ;
82
82
}
83
83
84
- bool NTPClient::forceUpdate () {
84
+ bool NTPClient::forceUpdate (unsigned long timeout) {
85
+ this ->sendNTPPacket ();
86
+
85
87
#ifdef DEBUG_NTPClient
86
- Serial.println (" Update from NTP Server" );
88
+ Serial.println (" [NTPClient] Waiting for NTP Server response... " );
87
89
#endif
88
90
89
- // flush any existing packets
90
- while (this ->_udp ->parsePacket () != 0 )
91
- this ->_udp ->flush ();
92
-
93
- this ->sendNTPPacket ();
94
-
95
91
// Wait till data is there or timeout...
96
- byte timeout = 0 ;
97
- int cb = 0 ;
98
- do {
99
- delay ( 10 );
100
- cb = this ->_udp ->parsePacket ();
101
- if (timeout > 100 ) return false ; // timeout after 1000 ms
102
- timeout++;
103
- } while (cb == 0 );
92
+ if (this ->receiveNTPPacket (timeout)) return true ;
104
93
105
- this ->_lastUpdate = millis () - (10 * (timeout + 1 )); // Account for delay in reading the time
106
-
107
- this ->_udp ->read (this ->_packetBuffer , NTP_PACKET_SIZE);
108
-
109
- unsigned long highWord = word (this ->_packetBuffer [40 ], this ->_packetBuffer [41 ]);
110
- unsigned long lowWord = word (this ->_packetBuffer [42 ], this ->_packetBuffer [43 ]);
111
- // combine the four bytes (two words) into a long integer
112
- // this is NTP time (seconds since Jan 1 1900):
113
- unsigned long secsSince1900 = highWord << 16 | lowWord;
94
+ #ifdef DEBUG_NTPClient
95
+ Serial.println (" [NTPClient] Timeout" );
96
+ #endif
97
+ return false ; // timeout
98
+ }
114
99
115
- this ->_currentEpoc = secsSince1900 - SEVENZYYEARS;
100
+ bool NTPClient::needUpdate () {
101
+ if (this ->_sendTime == 0 ) return true ; // Was never updated before.
102
+ if (millis () - this ->_sendTime >= this ->_updateInterval ) return true ; // Previous update was more than configured interval ago.
116
103
117
- return true ; // return true after successful update
104
+ return false ;
118
105
}
119
106
120
- bool NTPClient::update () {
121
- if ((millis () - this ->_lastUpdate >= this ->_updateInterval ) // Update after _updateInterval
122
- || this ->_lastUpdate == 0 ) { // Update if there was no update yet.
123
- if (!this ->_udpSetup || this ->_port != NTP_DEFAULT_LOCAL_PORT) this ->begin (this ->_port ); // setup the UDP client if needed
124
- return this ->forceUpdate ();
107
+ bool NTPClient::update (unsigned long timeout) {
108
+ if (this ->needUpdate ()) {
109
+ return this ->forceUpdate (timeout);
125
110
}
126
111
return false ; // return false if update does not occur
127
112
}
128
113
129
114
int NTPClient::asyncUpdate () {
130
- if ((millis () - this ->_sendTime >= this ->_updateInterval ) // Update after _updateInterval
131
- || this ->_sendTime == 0 ) { // Update if there was no update yet.
132
- _sendTime = millis ();
133
- if (!this ->_udpSetup || this ->_port != NTP_DEFAULT_LOCAL_PORT) this ->begin (this ->_port ); // setup the UDP client if needed
115
+ if (this ->needUpdate ()) {
134
116
this ->sendNTPPacket ();
135
117
136
- int code = 2 ;
137
- if (_needUpdate) code = -1 ; // timeout
118
+ if (_needUpdate) return -1 ; // return -1 if timeout
138
119
_needUpdate = true ;
139
- return code;
120
+ return 2 ; // return 2 if update is in progress
140
121
}
141
122
142
123
if (_needUpdate) {
143
- int cb = this ->_udp ->parsePacket ();
144
- if (cb == 0 ) return 2 ;
145
- this ->_udp ->read (this ->_packetBuffer , NTP_PACKET_SIZE);
146
-
147
- unsigned long highWord = word (this ->_packetBuffer [40 ], this ->_packetBuffer [41 ]);
148
- unsigned long lowWord = word (this ->_packetBuffer [42 ], this ->_packetBuffer [43 ]);
149
- // combine the four bytes (two words) into a long integer
150
- // this is NTP time (seconds since Jan 1 1900):
151
- unsigned long secsSince1900 = highWord << 16 | lowWord;
152
-
153
- this ->_currentEpoc = secsSince1900 - SEVENZYYEARS;
154
- this ->_lastUpdate = millis ();
124
+ if (!this ->receiveNTPPacket ()) return 2 ;
155
125
_needUpdate = false ;
156
126
return 0 ;
157
127
}
158
128
159
- return 1 ; // return false if update does not occur
129
+ return 1 ; // return 1 if update does not occur
160
130
}
161
131
162
132
bool NTPClient::isTimeSet () const {
163
133
return (this ->_lastUpdate != 0 ); // returns true if the time has been set, else false
164
134
}
165
135
166
136
long long NTPClient::getEpochTimeMillis () const {
167
- return this ->_currentEpoc * 1000LL + millis () - this ->_lastUpdate ;
137
+ return (this ->_timeOffset + // User offset
138
+ this ->_currentEpoch ) * 1000LL + // Epoch returned by the NTP server
139
+ (millis () - this ->_lastUpdate ); // Time since last update
168
140
}
169
141
170
142
unsigned long NTPClient::getEpochTime () const {
171
143
return this ->_timeOffset + // User offset
172
- this ->_currentEpoc + // Epoch returned by the NTP server
144
+ this ->_currentEpoch + // Epoch returned by the NTP server
173
145
((millis () - this ->_lastUpdate ) / 1000 ); // Time since last update
174
146
}
175
147
@@ -219,6 +191,13 @@ void NTPClient::setPoolServerName(const char* poolServerName) {
219
191
}
220
192
221
193
void NTPClient::sendNTPPacket () {
194
+ if (this ->_udpSetup ) {
195
+ // flush any existing packets
196
+ while (this ->_udp ->parsePacket () != 0 )
197
+ this ->_udp ->flush ();
198
+ }
199
+
200
+ if (!this ->_udpSetup ) this ->begin (this ->_port ); // setup the UDP client if needed
222
201
// set all bytes in the buffer to 0
223
202
memset (this ->_packetBuffer , 0 , NTP_PACKET_SIZE);
224
203
// Initialize values needed to form NTP request
@@ -241,6 +220,45 @@ void NTPClient::sendNTPPacket() {
241
220
}
242
221
this ->_udp ->write (this ->_packetBuffer , NTP_PACKET_SIZE);
243
222
this ->_udp ->endPacket ();
223
+ this ->_sendTime = millis ();
224
+
225
+ #ifdef DEBUG_NTPClient
226
+ Serial.println (" [NTPClient] Sent UDP packet" );
227
+ #endif
228
+ }
229
+
230
+ bool NTPClient::receiveNTPPacket (unsigned long timeout) {
231
+ int packetSize = this ->_udp ->parsePacket ();
232
+
233
+ if (packetSize < NTP_PACKET_SIZE) {
234
+ if (timeout == 0 ) return false ;
235
+
236
+ unsigned long start = millis ();
237
+ while (millis () - start < timeout) {
238
+ delay (1 );
239
+ packetSize = this ->_udp ->parsePacket ();
240
+ if (packetSize >= NTP_PACKET_SIZE) break ;
241
+ }
242
+ }
243
+
244
+ this ->_udp ->read (this ->_packetBuffer , NTP_PACKET_SIZE);
245
+
246
+ unsigned long highWord = word (this ->_packetBuffer [40 ], this ->_packetBuffer [41 ]);
247
+ unsigned long lowWord = word (this ->_packetBuffer [42 ], this ->_packetBuffer [43 ]);
248
+ // combine the four bytes (two words) into a long integer
249
+ // this is NTP time (seconds since Jan 1 1900):
250
+ unsigned long secsSince1900 = highWord << 16 | lowWord;
251
+
252
+ this ->_currentEpoch = secsSince1900 - SEVENTY_YEARS;
253
+ int latency = (millis () - this ->_sendTime );
254
+ this ->_lastUpdate = millis () - (latency / 2 ); // Account for latency in reading the time
255
+
256
+ #ifdef DEBUG_NTPClient
257
+ Serial.print (" [NTPClient] Received UDP packet latency: " );
258
+ Serial.println (latency);
259
+ #endif
260
+
261
+ return true ;
244
262
}
245
263
246
264
void NTPClient::setRandomPort (unsigned int minValue, unsigned int maxValue) {
0 commit comments