diff --git a/NTPClient.cpp b/NTPClient.cpp index 7b1a4e2..c7e9acd 100644 --- a/NTPClient.cpp +++ b/NTPClient.cpp @@ -22,150 +22,181 @@ #include "NTPClient.h" NTPClient::NTPClient(UDP& udp) { - this->_udp = &udp; + this->_udp = &udp; } NTPClient::NTPClient(UDP& udp, int timeOffset) { - this->_udp = &udp; - this->_timeOffset = timeOffset; + this->_udp = &udp; + this->_timeOffset = timeOffset; } NTPClient::NTPClient(UDP& udp, const char* poolServerName) { - this->_udp = &udp; - this->_poolServerName = poolServerName; + this->_udp = &udp; + this->_poolServerName = poolServerName; } NTPClient::NTPClient(UDP& udp, const char* poolServerName, int timeOffset) { - this->_udp = &udp; - this->_timeOffset = timeOffset; - this->_poolServerName = poolServerName; + this->_udp = &udp; + this->_timeOffset = timeOffset; + this->_poolServerName = poolServerName; } NTPClient::NTPClient(UDP& udp, const char* poolServerName, int timeOffset, int updateInterval) { - this->_udp = &udp; - this->_timeOffset = timeOffset; - this->_poolServerName = poolServerName; - this->_updateInterval = updateInterval; + this->_udp = &udp; + this->_timeOffset = timeOffset; + this->_poolServerName = poolServerName; + this->_updateInterval = updateInterval; } void NTPClient::begin() { - this->begin(NTP_DEFAULT_LOCAL_PORT); + this->begin(NTP_DEFAULT_LOCAL_PORT); } void NTPClient::begin(int port) { - this->_port = port; + this->_port = port; - this->_udp->begin(this->_port); + this->_udp->begin(this->_port); - this->_udpSetup = true; + this->_udpSetup = true; } bool NTPClient::forceUpdate() { #ifdef DEBUG_NTPClient - Serial.println("Update from NTP Server"); + Serial.println("Update from NTP Server"); #endif - this->sendNTPPacket(); + this->sendNTPPacket(); - // Wait till data is there or timeout... - byte timeout = 0; - int cb = 0; - do { - delay ( 10 ); - cb = this->_udp->parsePacket(); - if (timeout > 100) return false; // timeout after 1000 ms - timeout++; - } while (cb == 0); + // Wait till data is there or timeout... + byte timeout = 0; + int cb = 0; + do { + delay ( 10 ); + cb = this->_udp->parsePacket(); + if (timeout > 100) return false; // timeout after 1000 ms + timeout++; + } while (cb == 0); - this->_lastUpdate = millis() - (10 * (timeout + 1)); // Account for delay in reading the time + this->_lastUpdate = millis() - (10 * (timeout + 1)); // Account for delay in reading the time - this->_udp->read(this->_packetBuffer, NTP_PACKET_SIZE); + 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; + 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->_currentEpoc = secsSince1900 - SEVENZYYEARS; - return true; + return true; } bool NTPClient::update() { - if ((millis() - this->_lastUpdate >= this->_updateInterval) // Update after _updateInterval - || this->_lastUpdate == 0) { // Update if there was no update yet. - if (!this->_udpSetup) this->begin(); // setup the UDP client if needed - return this->forceUpdate(); - } - return true; + if ((millis() - this->_lastUpdate >= this->_updateInterval) // Update after _updateInterval + || this->_lastUpdate == 0) { // Update if there was no update yet. + if (!this->_udpSetup) this->begin(); // setup the UDP client if needed + return this->forceUpdate(); + } + return true; } unsigned long NTPClient::getEpochTime() { - return this->_timeOffset + // User offset - this->_currentEpoc + // Epoc returned by the NTP server - ((millis() - this->_lastUpdate) / 1000); // Time since last update + return this->_timeOffset + // User offset + this->_currentEpoc + // Epoc returned by the NTP server + ((millis() - this->_lastUpdate) / 1000); // Time since last update } int NTPClient::getDay() { - return (((this->getEpochTime() / 86400L) + 4 ) % 7); //0 is Sunday + return (((this->getEpochTime() / 86400L) + 4 ) % 7);//0 is Sunday } int NTPClient::getHours() { - return ((this->getEpochTime() % 86400L) / 3600); + return ((this->getEpochTime() % 86400L) / 3600); } int NTPClient::getMinutes() { - return ((this->getEpochTime() % 3600) / 60); + return ((this->getEpochTime() % 3600) / 60); } int NTPClient::getSeconds() { - return (this->getEpochTime() % 60); + return (this->getEpochTime() % 60); } String NTPClient::getFormattedTime() { - unsigned long rawTime = this->getEpochTime(); - unsigned long hours = (rawTime % 86400L) / 3600; - String hoursStr = hours < 10 ? "0" + String(hours) : String(hours); + unsigned long rawTime = this->getEpochTime(); + unsigned long hours = (rawTime % 86400L) / 3600; + String hoursStr = hours < 10 ? "0" + String(hours) : String(hours); - unsigned long minutes = (rawTime % 3600) / 60; - String minuteStr = minutes < 10 ? "0" + String(minutes) : String(minutes); + unsigned long minutes = (rawTime % 3600) / 60; + String minuteStr = minutes < 10 ? "0" + String(minutes) : String(minutes); - unsigned long seconds = rawTime % 60; - String secondStr = seconds < 10 ? "0" + String(seconds) : String(seconds); + unsigned long seconds = rawTime % 60; + String secondStr = seconds < 10 ? "0" + String(seconds) : String(seconds); - return hoursStr + ":" + minuteStr + ":" + secondStr; + return hoursStr + ":" + minuteStr + ":" + secondStr; +} + +String NTPClient::getFormattedDate() { // by Jordi Gras + unsigned long rawTime = this->getEpochTime(); + int daysMonth[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; // array index starts by 0 + double operador = 60*60*24*365; //secons, minutes, hours, days + double years = rawTime / operador; + + int leapYearsPast = floor(years / 4); + double resto = years - floor(years); + + int Year = 1970 + floor(years); // current year + // if it's leap change february + if ((Year%4 == 0) && ((Year%100 != 0) || (Year%400 == 0))) {daysMonth[1] = 29;} // put February in array + // final leap + int DaysOfYear = floor(resto * 365) - leapYearsPast; // days to end of year + + int Month = 0; + int suma = 0; + int Day = DaysOfYear; + while ((suma + daysMonth[Month]) <= DaysOfYear) { + suma = suma + daysMonth[Month]; + Day = Day - daysMonth[Month]; + Month++; + } + Month++; + String DayStr = Day < 10 ? "0" + String(Day) : String(Day); + String MonthStr = Month < 10 ? "0" + String(Month) : String(Month); + String YearStr = String(Year); + + return DayStr + "/" + MonthStr + "/" + YearStr; } void NTPClient::end() { - this->_udp->stop(); + this->_udp->stop(); - this->_udpSetup = false; + this->_udpSetup = false; } void NTPClient::setTimeOffset(int timeOffset) { - this->_timeOffset = timeOffset; + this->_timeOffset = timeOffset; } void NTPClient::setUpdateInterval(int updateInterval) { - this->_updateInterval = updateInterval; + this->_updateInterval = updateInterval; } void NTPClient::sendNTPPacket() { - // set all bytes in the buffer to 0 - memset(this->_packetBuffer, 0, NTP_PACKET_SIZE); - // Initialize values needed to form NTP request - // (see URL above for details on the packets) - this->_packetBuffer[0] = 0b11100011; // LI, Version, Mode - this->_packetBuffer[1] = 0; // Stratum, or type of clock - this->_packetBuffer[2] = 6; // Polling Interval - this->_packetBuffer[3] = 0xEC; // Peer Clock Precision - // 8 bytes of zero for Root Delay & Root Dispersion - this->_packetBuffer[12] = 49; - this->_packetBuffer[13] = 0x4E; - this->_packetBuffer[14] = 49; - this->_packetBuffer[15] = 52; - - // all NTP fields have been given values, now - // you can send a packet requesting a timestamp: - this->_udp->beginPacket(this->_poolServerName, 123); //NTP requests are to port 123 - this->_udp->write(this->_packetBuffer, NTP_PACKET_SIZE); - this->_udp->endPacket(); + // set all bytes in the buffer to 0 + memset(this->_packetBuffer, 0, NTP_PACKET_SIZE); + // Initialize values needed to form NTP request + // (see URL above for details on the packets) + this->_packetBuffer[0] = 0b11100011; // LI, Version, Mode + this->_packetBuffer[1] = 0; // Stratum, or type of clock + this->_packetBuffer[2] = 6; // Polling Interval + this->_packetBuffer[3] = 0xEC; // Peer Clock Precision + // 8 bytes of zero for Root Delay & Root Dispersion + this->_packetBuffer[12] = 49; + this->_packetBuffer[13] = 0x4E; + this->_packetBuffer[14] = 49; + this->_packetBuffer[15] = 52; + + // all NTP fields have been given values, now + // you can send a packet requesting a timestamp: + this->_udp->beginPacket(this->_poolServerName, 123); //NTP requests are to port 123 + this->_udp->write(this->_packetBuffer, NTP_PACKET_SIZE); + this->_udp->endPacket(); } diff --git a/NTPClient.h b/NTPClient.h index 4d5630d..f9c850c 100644 --- a/NTPClient.h +++ b/NTPClient.h @@ -1,4 +1,4 @@ -#pragma once +//#pragma once #include "Arduino.h" @@ -9,83 +9,89 @@ #define NTP_DEFAULT_LOCAL_PORT 1337 class NTPClient { - private: - UDP* _udp; - bool _udpSetup = false; - - const char* _poolServerName = "time.nist.gov"; // Default time server - int _port = NTP_DEFAULT_LOCAL_PORT; - int _timeOffset = 0; - - unsigned int _updateInterval = 60000; // In ms - - unsigned long _currentEpoc = 0; // In s - unsigned long _lastUpdate = 0; // In ms - - byte _packetBuffer[NTP_PACKET_SIZE]; - - void sendNTPPacket(); - - public: - NTPClient(UDP& udp); - NTPClient(UDP& udp, int timeOffset); - NTPClient(UDP& udp, const char* poolServerName); - NTPClient(UDP& udp, const char* poolServerName, int timeOffset); - NTPClient(UDP& udp, const char* poolServerName, int timeOffset, int updateInterval); - - /** - * Starts the underlying UDP client with the default local port - */ - void begin(); - - /** - * Starts the underlying UDP client with the specified local port - */ - void begin(int port); - - /** - * This should be called in the main loop of your application. By default an update from the NTP Server is only - * made every 60 seconds. This can be configured in the NTPClient constructor. - * - * @return true on success, false on failure - */ - bool update(); - - /** - * This will force the update from the NTP Server. - * - * @return true on success, false on failure - */ - bool forceUpdate(); - - int getDay(); - int getHours(); - int getMinutes(); - int getSeconds(); - - /** - * Changes the time offset. Useful for changing timezones dynamically - */ - void setTimeOffset(int timeOffset); - - /** - * Set the update interval to another frequency. E.g. useful when the - * timeOffset should not be set in the constructor - */ - void setUpdateInterval(int updateInterval); - - /** - * @return time formatted like `hh:mm:ss` - */ - String getFormattedTime(); - - /** - * @return time in seconds since Jan. 1, 1970 - */ - unsigned long getEpochTime(); - - /** - * Stops the underlying UDP client - */ - void end(); +private: +UDP* _udp; +bool _udpSetup = false; + +const char* _poolServerName = "time.nist.gov"; // Default time server +int _port = NTP_DEFAULT_LOCAL_PORT; +int _timeOffset = 0; + +unsigned int _updateInterval = 60000; // In ms + +unsigned long _currentEpoc = 0; // In s +unsigned long _lastUpdate = 0; // In ms + +byte _packetBuffer[NTP_PACKET_SIZE]; + +void sendNTPPacket(); + +public: +NTPClient(UDP& udp); +NTPClient(UDP& udp, int timeOffset); +NTPClient(UDP& udp, const char* poolServerName); +NTPClient(UDP& udp, const char* poolServerName, int timeOffset); +NTPClient(UDP& udp, const char* poolServerName, int timeOffset, int updateInterval); + +/** + * Starts the underlying UDP client with the default local port + */ +void begin(); + + +/** + * Starts the underlying UDP client with the specified local port + */ +void begin(int port); + +/** + * This should be called in the main loop of your application. By default an update from the NTP Server is only + * made every 60 seconds. This can be configured in the NTPClient constructor. + * + * @return true on success, false on failure + */ +bool update(); + +/** + * This will force the update from the NTP Server. + * + * @return true on success, false on failure + */ +bool forceUpdate(); + +int getDay(); +int getHours(); +int getMinutes(); +int getSeconds(); + +/** + * Changes the time offset. Useful for changing timezones dynamically + */ +void setTimeOffset(int timeOffset); + +/** + * Set the update interval to another frequency. E.g. useful when the + * timeOffset should not be set in the constructor + */ +void setUpdateInterval(int updateInterval); + +/** + * @return time formatted like `hh:mm:ss` + */ +String getFormattedTime(); + +/** + * @return time formatted date `dd/MM/yy` + */ +String getFormattedDate(); // by Jordi Gras + +/** + * @return time in seconds since Jan. 1, 1970 + */ +unsigned long getEpochTime(); + +/** + * Stops the underlying UDP client + */ +void end(); };