pcklz
New member
Нашел и отладил утилиты синхронизации времени с NTP сервером, конвертации времени из UNIX формата (число секунд с 01.01.1970) в обычный и обратно. Что очень полезно для программирования событий на ESP 8266. Естественно, чтобы использовать их, необходимо, чтобы ESP8266 была подключена к сети с выходом в интернет. До того, как произойдет синхронизация (может не произойти с первого раза), она пытается это делать каждые 10 секунд, после этого - раз в сутки, т.к. есть встроенные часы по таймеру Tcker.h
Также прикладываю утилиты конвертации IP адреса в/из строкового формата.
Код:#include <WiFiUdp.h> #include <Ticker.h> /*******************настройки для NTP-синхронизации времени****************/ #define GMT 3 bool AskNTPTime=false; unsigned int udpPort = 2390; // local port to listen for UDP packets IPAddress timeServerIP; // time.nist.gov NTP server address const char* ntpServerName = "time.nist.gov"; const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets WiFiUDP udp; /*******************настройки времени и даты*******************************/ uint8_t blink_loop = 0; uint16_t frequency, blink_mode = 0; uint8_t hour, minute, second, day, month, year, weekday; uint8_t monthDays[12]={31,28,31,30,31,30,31,31,30,31,30,31}; unsigned long secsUnix; unsigned long Tm_blink; Ticker timer; IPAddress ip, gateway, subnet; void setup(void) { Serial.begin(115200); Serial.println(); timer.attach(1, timerTime); Serial.println("Starting UDP"); udp.begin(udpPort); Serial.print("Local port: "); Serial.println(udp.localPort()); } void loop() { if ( WiFi.status() == WL_CONNECTED) { if(AskNTPTime==true) { if(hour==0 && minute==0 && second<2) AskNTPTime==false; } else if(second%10<2) Ask_NTP_Time(); } } void timerTime() { if(AskNTPTime==true) secsUnix++; // если время синхронизировано, то отсчитываем время в секундах second++; // ведем реальный отсчет времени if (second > 59) { second = 0; minute++; if (minute > 59) { minute = 0; hour++; if (hour > 23) { hour = 0; day++; if(month>1) if(day>monthDays[month-1]) { day=1; month++; if(month>12) { year++; month=1; } } } } } } String IP_to_String(IPAddress ip) { return(String(ip[0])+"."+String(ip[1])+"."+String(ip[2])+"."+String(ip[3])); } IPAddress String_to_IP(String strIP) { int Parts[4] = {0,0,0,0}; int Part = 0; for ( byte i=0; i<strIP.length(); i++ ) { char c = strIP.charAt(i); if ( c == '.' ) { Part++; continue; } if ( c<48 || c>57 ) continue; // не цифровой символ Parts[Part] *= 10; Parts[Part] += c - '0'; } IPAddress ip_str( Parts[0], Parts[1], Parts[2], Parts[3] ); return(ip_str); } bool Ask_NTP_Time() { int cb; while (udp.parsePacket() > 0) {delay(1);} WiFi.hostByName(ntpServerName, timeServerIP); sendNTPpacket(timeServerIP); // send an NTP packet to a time server // wait to see if a reply is available unsigned long beginWait = millis(); while (millis() - beginWait < 2000) { cb = udp.parsePacket(); if (cb >= NTP_PACKET_SIZE) { Serial.print("packet received, length="); Serial.println(cb); // We've received a packet, read the data from it udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer //the timestamp starts at byte 40 of the received packet and is four bytes, // or two words, long. First, esxtract the two words: unsigned long secsSince1900; secsSince1900 = (unsigned long)packetBuffer[40] << 24; secsSince1900 |= (unsigned long)packetBuffer[41] << 16; secsSince1900 |= (unsigned long)packetBuffer[42] << 8; secsSince1900 |= (unsigned long)packetBuffer[43]; Serial.print("Seconds since Jan 1 1900 = " ); Serial.println(secsSince1900); // Unix time starts on Jan 1 1970. In seconds, that's 2208988800: const unsigned long seventyYears = 2208988800UL; // subtract seventy years: secsUnix = secsSince1900 - seventyYears; // print Unix time: Serial.print("Unix time = "); Serial.println(secsUnix); Unix_to_GMT(secsUnix); AskNTPTime=true; // признак того, что время синхронизировано // выдерживаем паузу while (millis() - beginWait < 3000) {delay(10);} Serial.print("The UTC time is "); // UTC is the time at Greenwich Meridian (GMT) Serial.println(Time_to_String()); return(true); } } Serial.println("No packet yet"); while (millis() - beginWait < 1000) {delay(10);} return(false); // wait ten seconds before asking for the time again } // send an NTP request to the time server at the given address unsigned long sendNTPpacket(IPAddress & address) { Serial.println("sending NTP packet...IP="+IP_to_String(address)); // set all bytes in the buffer to 0 memset(packetBuffer, 0, NTP_PACKET_SIZE); // Initialize values needed to form NTP request // (see URL above for details on the packets) 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 // 8 bytes of zero for Root Delay & Root Dispersion packetBuffer[12] = 49; packetBuffer[13] = 0x4E; packetBuffer[14] = 49; packetBuffer[15] = 52; // all NTP fields have been given values, now // you can send a packet requesting a timestamp: udp.beginPacket(address, 123); //NTP requests are to port 123 udp.write(packetBuffer, NTP_PACKET_SIZE); udp.endPacket(); } void Unix_to_GMT(unsigned long epoch) { // корректировка часового пояса и синхронизация epoch = epoch + GMT * 3600; second=epoch%60; epoch/=60; // now it is minutes minute=epoch%60; epoch/=60; // now it is hours hour=epoch%24; epoch/=24; // now it is days weekday=(epoch+4)%7; // day week, 0-sunday year=70; int days=0; while(days + ((year % 4) ? 365 : 366) <= epoch) { days += (year % 4) ? 365 : 366; year++; } epoch -= days; // now it is days in this year, starting at 0 days=0; month=0; byte monthLength=0; for (month=0; month<12; month++) { if (month==1) { // february if (year%4) monthLength=28; else monthLength=29; } else monthLength = monthDays[month]; if (epoch>=monthLength) epoch-=monthLength; else break; } month++; // jan is month 1 day=epoch+1; // day of month } String Time_to_String() { String Tm,wd; int k,n; switch(weekday) { case 0: wd="su";; break; case 1: wd="mo";; break; case 2: wd="tu";; break; case 4: wd="th";; break; case 5: wd="fr";; break; case 6: wd="sf";; break; } k=day/10; n=day%10; Tm=String(k)+String(n)+"."; k=month/10; n=month%10; Tm=Tm+String(k)+String(n)+"."; k=1900+year; Tm=Tm+String(k)+","+wd+" "; k=hour/10; n=hour%10; Tm=Tm+String(k)+String(n)+":"; k=minute/10; n=minute%10; Tm=Tm+String(k)+String(n)+":"; k=second/10; n=second%10; Tm=Tm+String(k)+String(n); return(Tm); } unsigned long GMT_to_Unix(byte y,byte mon,byte d,byte h,byte mt,byte s) { // считает количество секунд от текущего времени до времени d.mon.y h:mt:s unsigned long epoch=0; epoch+=s; epoch+=mt*60; epoch+=h*3600; d--; epoch+=d*24*3600; mon--; byte monthLength; for (int m=mon; m>=1; m--) { if (m==2) { // february if (year%4) monthLength=28; else monthLength=29; } else monthLength = monthDays[m-1]; epoch+=monthLength*24*3600; } y--; int days=0; while(y>=70) { days += (y % 4) ? 365 : 366; y--; } epoch+=days*24*3600; epoch = epoch - GMT * 3600; return(epoch); }
Здравствуйте, можете скинуть сайт или саму библиотеку wifiudp.h нигде не могу ее найти