Skip to content

Commit 9a35813

Browse files
committed
Refactor loop() method to avoid blocking.
1 parent 894b21d commit 9a35813

File tree

2 files changed

+62
-34
lines changed

2 files changed

+62
-34
lines changed

NTPClient.cpp

+59-34
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/**
22
* The MIT License (MIT)
3-
* Copyright (c) 2015 by Fabrice Weinberg
3+
* Original work Copyright (c) 2015 by Fabrice Weinberg
4+
* Modified work Copyright (c) 2020 by Thomas Haggett
45
*
56
* Permission is hereby granted, free of charge, to any person obtaining a copy
67
* of this software and associated documentation files (the "Software"), to deal
@@ -82,48 +83,72 @@ void NTPClient::begin(int port) {
8283
}
8384

8485
bool NTPClient::forceUpdate() {
85-
#ifdef DEBUG_NTPClient
86-
Serial.println("Update from NTP Server");
87-
#endif
88-
89-
// flush any existing packets
90-
while(this->_udp->parsePacket() != 0)
91-
this->_udp->flush();
86+
this->_lastUpdate = 0;
87+
this->_requestSent = 0;
88+
this->_requestDelay = 1;
89+
return true;
90+
}
9291

93-
this->sendNTPPacket();
92+
bool NTPClient::update() {
93+
int now = millis();
9494

95-
// 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);
95+
if(!this->_udpSetup)
96+
this->begin();
10497

105-
this->_lastUpdate = millis() - (10 * (timeout + 1)); // Account for delay in reading the time
98+
// are we due to send a request?
99+
if(this->_lastUpdate > 0 && now < this->_lastUpdate + this->_updateInterval) {
100+
// update isn't due. carry on.
101+
return false;
102+
}
106103

107-
this->_udp->read(this->_packetBuffer, NTP_PACKET_SIZE);
104+
// we're due an update - have we sent a request and it has timed out,
105+
// or not actually sent a request yet?
106+
if(this->_requestSent == 0 || now > this->_requestSent + this->_requestDelay + REQUEST_TIMEOUT) {
107+
// if we had already sent a request, let's bump up the _requestDelay so we don't constantly
108+
// hammer a potentially down NTP server!
109+
if(this->_requestSent > 0) {
110+
this->_requestDelay *= 2;
111+
if(this->_requestDelay > 30000)
112+
this->_requestDelay = 30000;
113+
} else {
114+
// this is the first time we're attempting a send.
115+
// purge any old packets that might be buffered
116+
while(this->_udp->parsePacket() != 0) {
117+
this->_udp->flush();
118+
}
119+
}
120+
121+
// Right. Send an NTP packet!
122+
// Serial.printf("Sending an NTP packet (timeout=%i)!\n", this->_requestDelay + REQUEST_TIMEOUT);
123+
this->sendNTPPacket();
124+
125+
// remember when we last sent a request
126+
this->_requestSent = now;
127+
}
108128

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;
129+
// check for any replies!
130+
int length = this->_udp->parsePacket();
131+
if( length > 0 ) {
132+
Serial.println("Got an NTP reply!");
133+
this->_udp->read(this->_packetBuffer, NTP_PACKET_SIZE);
134+
this->_udp->flush();
114135

115-
this->_currentEpoc = secsSince1900 - SEVENZYYEARS;
136+
unsigned long highWord = word(this->_packetBuffer[40], this->_packetBuffer[41]);
137+
unsigned long lowWord = word(this->_packetBuffer[42], this->_packetBuffer[43]);
138+
// combine the four bytes (two words) into a long integer
139+
// this is NTP time (seconds since Jan 1 1900):
140+
unsigned long secsSince1900 = highWord << 16 | lowWord;
116141

117-
return true; // return true after successful update
118-
}
142+
this->_currentEpoc = secsSince1900 - SEVENZYYEARS;
119143

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->begin(); // setup the UDP client if needed
124-
return this->forceUpdate();
144+
// cleanup and reset our state
145+
this->_requestSent = 0;
146+
this->_requestDelay = 1;
147+
this->_lastUpdate = now;
148+
return true;
125149
}
126-
return false; // return false if update does not occur
150+
151+
return false;
127152
}
128153

129154
unsigned long NTPClient::getEpochTime() const {

NTPClient.h

+3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ class NTPClient {
2323
unsigned long _currentEpoc = 0; // In s
2424
unsigned long _lastUpdate = 0; // In ms
2525

26+
unsigned long _requestSent = 0; // in ms (when the last request was sent)
27+
unsigned long _requestDelay = 1; // in ms (a cumulative delay to slow down constant failures)
28+
2629
byte _packetBuffer[NTP_PACKET_SIZE];
2730

2831
void sendNTPPacket();

0 commit comments

Comments
 (0)