Lightweight WIZnet W5500 NTPClient library. Includes DST and set RTC options.

Dependents:   W5500-SNTPClient-example

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;}
+}