Lightweight WIZnet W5500 NTPClient library. Includes DST and set RTC options.
Dependents: W5500-SNTPClient-example
Diff: SNTPClient.cpp
- Revision:
- 0:f8cb34a007a4
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SNTPClient.cpp Thu May 02 20:46:54 2019 +0000 @@ -0,0 +1,73 @@ +#include "SNTPClient.h" +#include "UDPSocket.h" + +#define MAX_TRY_WRITE 10 +#define MAX_TRY_READ 10 + +SNTPClient::SNTPClient() : socket() +{ + +} + +uint32_t SNTPClient::getNTP(char * NTPpool,uint32_t tzoffset, bool dst, uint32_t setRTC) +{ + uint32_t NTP_PACKET_SIZE = 48; + char packetBuffer[NTP_PACKET_SIZE]; + uint32_t NTP_OFFSET = 2208988800; // UTC time + memset(packetBuffer, 0x00, NTP_PACKET_SIZE); + // Initialize values needed to form NTP request + packetBuffer[0] = 0b11100011; // LI, Version, Mode + packetBuffer[1] = 0; // Stratum, or type of clock + packetBuffer[2] = 6; // Polling Interval + packetBuffer[3] = 0xEC; // Peer Clock Precision + // [4]-[11]: 8 bytes of zero for Root Delay & Root Dispersion + packetBuffer[12] = 49; + packetBuffer[13] = 0x4E; + packetBuffer[14] = 49; + packetBuffer[15] = 52; + uint32_t recv_size = 0; + uint32_t tries1 = MAX_TRY_WRITE; + while ((recv_size != NTP_PACKET_SIZE) && (tries1 > 0)){ + tries1--; + socket.set_blocking(false, 3000); // allow 500mS seconds to connect to remote server + socket.init(); + socket.bind(0); + if(sntp_server.set_address(NTPpool, 123) < 0) + return false; + socket.set_blocking(false, 200); // check for response 200mS intervals + socket.sendTo(sntp_server, packetBuffer, NTP_PACKET_SIZE); + uint32_t tries2 = MAX_TRY_READ; + while ((recv_size != NTP_PACKET_SIZE) && (tries2 > 0)){ + tries2--; + wait_ms(20); + recv_size = socket.receiveFrom(sntp_server, packetBuffer, NTP_PACKET_SIZE); + } + socket.close(); + } + if(recv_size==48){ + uint32_t secsSince1970=((packetBuffer[40]<<24)|(packetBuffer[41]<<16)|(packetBuffer[42]<<8)|packetBuffer[43])-NTP_OFFSET; + uint32_t CETtime=(secsSince1970+(tzoffset*3600)); + // check for DST time change, only valid for europe!!! + // see http://www.instructables.com/id/The-Arduino-and-Daylight-Saving-Time-Europe/ + uint32_t DST=0; + if(dst){ + uint32_t dow,hour,day,month; + char buffer[10]; + strftime(buffer, 2,"%H", localtime(&CETtime)); + hour = atoi(buffer); + strftime(buffer, 2,"%w", localtime(&CETtime)); + dow = atoi(buffer); + strftime(buffer, 2,"%e", localtime(&CETtime)); + day = atoi(buffer); + strftime(buffer, 2,"%m", localtime(&CETtime)); + month = atoi(buffer); + uint32_t previousSunday = day - dow; + if (month > 2 && month < 9){DST=3600;} + if (month == 2 && previousSunday >= 25 && hour >= 2){DST=3600;} // DST starts 2nd Sunday of March; 2am + if (month == 9 && previousSunday < 25 && hour >= 2){DST=0;} // DST ends 1st Sunday of November; 2am + } + if (setRTC){set_time(CETtime+DST+1);} // todo: add timer code to addjust fractional second to offset MCU processing delay + return (CETtime+DST); + } + else{return 0;} +}