From 0ccc182d7f55d95c8808efc26a8b8d68a8c27995 Mon Sep 17 00:00:00 2001 From: HoustonAsh Date: Tue, 9 Apr 2024 19:22:04 +0800 Subject: [PATCH 1/4] feat: async update --- NTPClient.cpp | 37 +++++++++++++++++++++++++++++++++++++ NTPClient.h | 16 ++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/NTPClient.cpp b/NTPClient.cpp index b435855..760068c 100755 --- a/NTPClient.cpp +++ b/NTPClient.cpp @@ -126,10 +126,47 @@ bool NTPClient::update() { return false; // return false if update does not occur } +int NTPClient::asyncUpdate() { + if ((millis() - this->_sendTime >= this->_updateInterval) // Update after _updateInterval + || this->_sendTime == 0) { // Update if there was no update yet. + _sendTime = millis(); + if (!this->_udpSetup || this->_port != NTP_DEFAULT_LOCAL_PORT) this->begin(this->_port); // setup the UDP client if needed + this->sendNTPPacket(); + + int code = 2; + if (_needUpdate) code = -1; // timeout + _needUpdate = true; + return code; + } + + if (_needUpdate) { + int cb = this->_udp->parsePacket(); + if (cb == 0) return 2; + this->_udp->read(this->_packetBuffer, NTP_PACKET_SIZE); + + unsigned long highWord = word(this->_packetBuffer[40], this->_packetBuffer[41]); + unsigned long lowWord = word(this->_packetBuffer[42], this->_packetBuffer[43]); + // combine the four bytes (two words) into a long integer + // this is NTP time (seconds since Jan 1 1900): + unsigned long secsSince1900 = highWord << 16 | lowWord; + + this->_currentEpoc = secsSince1900 - SEVENZYYEARS; + this->_lastUpdate = millis(); + _needUpdate = false; + return 0; + } + + return 1; // return false if update does not occur +} + bool NTPClient::isTimeSet() const { return (this->_lastUpdate != 0); // returns true if the time has been set, else false } +long long NTPClient::getEpochTimeMillis() const { + return this->_currentEpoc * 1000LL + millis() - this->_lastUpdate; +} + unsigned long NTPClient::getEpochTime() const { return this->_timeOffset + // User offset this->_currentEpoc + // Epoch returned by the NTP server diff --git a/NTPClient.h b/NTPClient.h index a31d32f..e89dfe3 100755 --- a/NTPClient.h +++ b/NTPClient.h @@ -20,6 +20,8 @@ class NTPClient { unsigned long _updateInterval = 60000; // In ms + bool _needUpdate = true; + unsigned long _sendTime = 0; unsigned long _currentEpoc = 0; // In s unsigned long _lastUpdate = 0; // In ms @@ -74,6 +76,14 @@ class NTPClient { */ bool forceUpdate(); + /** + * Alternatevly this can be called instead of update() in the main loop of your application. + * AsyncUpdate from the NTP Server is made every _updateInterval milliseconds. + * + * @return 0 on success, -1 on failure, 1 if no update is needed, 2 if update is in progress + */ + int asyncUpdate(); + /** * This allows to check if the NTPClient successfully received a NTP packet and set the time. * @@ -107,6 +117,12 @@ class NTPClient { */ unsigned long getEpochTime() const; + + /** + * @return time in milliseconds since Jan. 1, 1970 (UTC+0) + */ + long long getEpochTimeMillis() const; + /** * Stops the underlying UDP client */ From 36d6a23b56bcb3ee59013939c9e8d4402e2b285b Mon Sep 17 00:00:00 2001 From: HoustonAsh Date: Tue, 9 Apr 2024 19:27:06 +0800 Subject: [PATCH 2/4] feat: new example for async update --- examples/AsyncUpdate/AsyncUpdate.ino | 48 ++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 examples/AsyncUpdate/AsyncUpdate.ino diff --git a/examples/AsyncUpdate/AsyncUpdate.ino b/examples/AsyncUpdate/AsyncUpdate.ino new file mode 100644 index 0000000..95bd1ec --- /dev/null +++ b/examples/AsyncUpdate/AsyncUpdate.ino @@ -0,0 +1,48 @@ +#include +#include + +#include "NTPClient.h" + +#define SSID "" +#define PASSWORD "" + +WiFiUDP ntpUDP; +NTPClient timeClient(ntpUDP, "0.asia.pool.ntp.org", 0, 1500); + +void setup(){ + Serial.begin(115200); + + WiFi.begin(SSID, PASSWORD); + + while ( WiFi.status() != WL_CONNECTED ) { + delay ( 500 ); + Serial.print ( "." ); + } + + timeClient.begin(); +} + +void loop() { + long int loopMillis = millis(); + static int prevRes = 0; + // with update() method loop will be blocked until time is updated + // timeClient.update(); + int res = timeClient.asyncUpdate(); + + if (res != prevRes) { + Serial.printf("Result: %d\n", res); + prevRes = res; + } + + static long int lm = 0; + + if (millis() - lm > 1000) { + lm = millis(); + Serial.printf("%s.%d\n", timeClient.getFormattedTime().c_str(), int(timeClient.getEpochTimeMillis()%1000)); + } + + long int dd = millis() - loopMillis; + if (dd > 10) { + Serial.printf("Loop took %d ms...\n", dd); + } +} \ No newline at end of file From 671e503c969167a3b33fe0347ce5f9866fdaa0ac Mon Sep 17 00:00:00 2001 From: HoustonAsh Date: Tue, 9 Apr 2024 19:41:24 +0800 Subject: [PATCH 3/4] fix: asyncUpdate example --- examples/AsyncUpdate/AsyncUpdate.ino | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/AsyncUpdate/AsyncUpdate.ino b/examples/AsyncUpdate/AsyncUpdate.ino index 95bd1ec..ce9fd86 100644 --- a/examples/AsyncUpdate/AsyncUpdate.ino +++ b/examples/AsyncUpdate/AsyncUpdate.ino @@ -1,8 +1,10 @@ -#include +#include +// change next line to use with another board/shield +#include +//#include // for WiFi shield +//#include // for WiFi 101 shield or MKR1000 #include -#include "NTPClient.h" - #define SSID "" #define PASSWORD "" From e370ab622d55d1f97aabccbeb66c7b3f51d69c75 Mon Sep 17 00:00:00 2001 From: HoustonAsh Date: Tue, 9 Apr 2024 19:48:42 +0800 Subject: [PATCH 4/4] cfg: pkg version --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index abdd80d..5ff7998 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=NTPClient -version=3.2.1 +version=3.3.1 author=Fabrice Weinberg maintainer=Fabrice Weinberg sentence=An NTPClient to connect to a time server