синхронизация с мировым временем

Maverik
Offline
Зарегистрирован: 12.09.2012

по поводу неточности таймера 1307 и внутреннего генератора вопрос - у кого-нибудь есть готовый код синхронизации с мировым временем ?

Coolerr
Offline
Зарегистрирован: 30.06.2014

GPS

Araris
Offline
Зарегистрирован: 09.11.2012


#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
}