синхронизация с мировым временем
- Войдите на сайт для отправки комментариев
Пнд, 15/12/2014 - 16:07
по поводу неточности таймера 1307 и внутреннего генератора вопрос - у кого-нибудь есть готовый код синхронизации с мировым временем ?
GPS
#include <EthernetUdp.h> #include <DS_1302.h> #define DEBUG 1 #define DS1302_RST 4 // DS1302 RST #define DS1302_IO 5 // DS1302 I/O #define DS1302_SCK 6 // DS1302 SCK #define NTP_INTERVAL 1800000 byte timeServer[] = {193,204,114,232}; int TimeZone = 2; unsigned long ntp_request_interval = 60000; unsigned long ntp_last_request_time = 0; EthernetUDP Udp_; Time CurTime; static int CurYear = 0; static int CurMonth = 0; static int CurDay = 0; static int CurDayOfWeek = 0; static int CurTimeHour = 0; static int CurTimeMin = 0; static int CurTimeSec = 0; DS1302 rtc(DS1302_RST,DS1302_IO,DS1302_SCK); void setup () { rtc.halt(false); rtc.writeProtect(false); } void loop() { //////////////////// NTP request if ( millis() < ntp_last_request_time ) { ntp_last_request_time = millis(); } // after millis() overflow if ( millis() - ntp_last_request_time > ntp_request_interval ) { getNtpTime(); } } void getNtpTime() { Udp_.begin(8888); byte pb[48]; pb[0] = 0b11100011; pb[1] = 0; pb[2] = 6; pb[3] = 0xEC; pb[12] = 49; pb[13] = 0x4E; pb[14] = 49; pb[15] = 52; Udp_.beginPacket(timeServer, 123); Udp_.write(pb,48); Udp_.endPacket(); uint32_t beginWait = millis(); while (millis() - beginWait < 2000) { int size = Udp_.parsePacket(); if (size >= 48) { #ifdef DEBUG Serial.print("Receive NTP Response "); #endif Udp_.read(pb, 48); unsigned long t1, t2, t3, t4; t1 = t2 = t3 = t4 = 0; for ( int i=0; i < 4; i++ ) { t1 = t1 << 8 | pb[16+i]; t2 = t2 << 8 | pb[24+i]; t3 = t3 << 8 | pb[32+i]; t4 = t4 << 8 | pb[40+i]; } float f1,f2,f3,f4; f1 = ((long)pb[20] * 256 + pb[21]) / 65536.0; f2 = ((long)pb[28] * 256 + pb[29]) / 65536.0; f3 = ((long)pb[36] * 256 + pb[37]) / 65536.0; f4 = ((long)pb[44] * 256 + pb[45]) / 65536.0; const unsigned long seventyYears = 2208988800UL; t1 -= seventyYears; t2 -= seventyYears; t3 -= seventyYears; t4 -= seventyYears; t4 += (TimeZone * 3600L); // Adjust timezone t4 += 1; // adjust the delay(1000) at begin of loop! if (f4 > 0.4) t4++; // adjust fractional part, see above const uint8_t daysInMonth [] PROGMEM = { 31,28,31,30,31,30,31,31,30,31,30,31 }; t4 -= 946684800; // bring to 2000 timestamp from 1970 uint8_t ss = t4 % 60; t4 /= 60; uint8_t mm = t4 % 60; t4 /= 60; uint8_t hh = t4 % 24; uint16_t days = t4 / 24; uint8_t leap; uint16_t yOff; for ( yOff = 0; ; ++yOff ) { leap = yOff % 4 == 0; if (days < 365 + leap) break; days -= 365 + leap; } uint8_t m; for ( m = 1; ; ++m ) { uint8_t daysPerMonth = pgm_read_byte(daysInMonth + m - 1); if (leap && m == 2) ++daysPerMonth; if (days < daysPerMonth) break; days -= daysPerMonth; } uint8_t d = days + 1; rtc.setTime(hh, mm, ss); rtc.setDate(d, m, yOff); CurTime = rtc.getTime(); CurTimeHour = CurTime.hour; CurTimeMin = CurTime.min; CurTimeSec = CurTime.sec; CurDay = CurTime.date; CurDayOfWeek = CurTime.dow; CurMonth = CurTime.mon; CurYear = CurTime.year; ntp_request_interval = NTP_INTERVAL; #ifdef DEBUG Serial.println("NTP SyncTime OK"); #endif } } Udp_.stop(); ntp_last_request_time = millis(); #ifdef DEBUG Serial.print(CurTimeHour); Serial.print(":"); Serial.print(CurTimeMin); Serial.print(":"); Serial.print(CurTimeSec); Serial.print(" "); Serial.print(CurDay); Serial.print("."); Serial.print(CurMonth); Serial.print("."); Serial.print(CurYear); Serial.println(); #endif }