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

peerat
Offline
Зарегистрирован: 26.10.2015

Добрый день! Уже несколько дней бьюсь над вопросом синхронизации времени от NTP сервера, что бы потом синхронизировать RTC DS3231. исходный железки: Arduino MEGA2560 ENC28J60 DS3231 При определенных условиях синхронизация все же работает. Если я посылаю запросы на сервер времени моего провайдера (пинг до которого 1 мс), то работает, но сначала некоторое время запросы уходят в пустоту и ответов я не получаю, но потом минут через 5 примерно, сервер начинает отвечать точным временем!! и даже так и продолжает отвечать. Но так и не получается достутчатся до других NTP серверов. И еще не понятный момент, порт NTP 123, но почему то ответы начинают приниматся когда порт указан 0... Кто сталкивался с синхронизацией помогите пожалуйста


       #include <EtherCard.h>

        #define SECONDS_IN_DAY          86400
        #define START_YEAR              1900
        #define TIME_ZONE               +3
        static int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

        static byte mymac[] = {0x00,0x1A,0x4B,0x38,0x0C,0x5C};
        byte Ethernet::buffer[2000];


        static byte myip[] = { 192, 168, 1, 40 };
        static byte mygw[] = { 192, 168, 1 , 1 };
        static byte mymask[] = { 255, 255, 255, 0 };
        static byte mydns[] = { 0, 0, 0, 0 };
//        static byte ntpServer[] = {95,66,187,242};
        static byte srcPort = 0;
        
        uint32_t timeStamp;
        boolean requestSent;
        
        #define INTERVAL                10000
        unsigned long lastTimeSync = 0;

void setup () {
      Serial.begin(57600);
      Serial.println("NTP Demo");
 
  if (!ether.begin(sizeof Ethernet::buffer, mymac, 53))
    Serial.println( "Failed to access Ethernet controller");
 else
   Serial.println("Ethernet controller initialized");
 
  if (!ether.dhcpSetup())
    Serial.println("Failed to get configuration from DHCP");
  else
  ether.staticSetup(myip, mygw, mydns, mymask);
  Serial.println("DHCP configuration done");
  ether.printIp("IP:   ", ether.myip); // output IP address to Serial
  ether.printIp("GW:   ", ether.gwip); // output gateway address to Serial
  ether.printIp("DNS:  ", ether.dnsip); // output gateway address to Serial
  ether.printIp("Mask: ", ether.netmask); // output netmask to Serial
  ether.printIp("DHCP: ", ether.dhcpip); // output IP address of the DHCP server
  
  Serial.println();
  requestSent = false;
}
 
void loop() 
  {
  static byte ntpServer[] = {23,99,222,162};
  unsigned long timeSync = millis();
  if(timeSync - lastTimeSync > INTERVAL)
    {
    Serial.println("request sent");
    int i = 0;
    while (i<1)
       {
       ether.ntpRequest(ntpServer, 0);
       ether.packetLoop(ether.packetReceive());
       int j = 0;
       while (j<1)
        {
         if(ether.ntpProcessAnswer(&timeStamp, 0)) 
           {
           correctTime(timeStamp + 3600 * TIME_ZONE);
           requestSent = false;
           }
        j++;
        }
       i++;
       }
       lastTimeSync = timeSync;
    }
  delay(1000);
  }






void correctTime(uint32_t timeStamp) 
  {
  unsigned int year = START_YEAR;
  while(1) 
    {
    uint32_t seconds;
    if(isLeapYear(year)) seconds = SECONDS_IN_DAY * 366;
    else seconds = SECONDS_IN_DAY * 365;
    if(timeStamp >= seconds) 
      {
      timeStamp -= seconds;
      year++;
      } 
    else break;
    }
  unsigned int month = 0;
  while(1) 
    {    
    uint32_t seconds = SECONDS_IN_DAY * days_in_month[month];
    if(isLeapYear(year) && month == 1) seconds = SECONDS_IN_DAY * 29;
    if(timeStamp >= seconds) 
      {
      timeStamp -= seconds;
      month++;
      }
    else break;
    }  
    month++;
  unsigned int day = 1;
  while(1) 
    {
    if(timeStamp >= SECONDS_IN_DAY) 
      {
      timeStamp -= SECONDS_IN_DAY;
      day++;
      }
    else break;
    } 
  unsigned int hour = timeStamp / 3600;
  unsigned int minute = (timeStamp - (uint32_t)hour * 3600) / 60;
  unsigned int second = (timeStamp - (uint32_t)hour * 3600) - minute * 60;
  


  if(day < 10) Serial.print("0");
  Serial.print(day);
  Serial.print("/");
  
  if(month < 10) Serial.print("0");
  Serial.print(month);
  Serial.print("/");  
  
  Serial.println(year);
  
  if(hour < 10) Serial.print("0");
  Serial.print(hour);
  Serial.print(":");
  
  if(minute < 10) Serial.print("0");
  Serial.print(minute);
  Serial.print(":");
  
  if(second < 10) Serial.print("0");
  Serial.println(second);
  
  Serial.println();
  }

boolean isLeapYear(unsigned int year) 
  {
  return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
  }

 

 

 

 

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

строка 15 ваш днс сервер где?, лучше определять по имени а не по ip

попробовать с компа пропинговать ntp сервера

peerat
Offline
Зарегистрирован: 26.10.2015

почему это лучше определять по имени?

NTP сервера пингуются

Radjah
Offline
Зарегистрирован: 06.08.2014
$host 0.debian.pool.ntp.org
0.debian.pool.ntp.org has address 46.46.152.214
0.debian.pool.ntp.org has address 188.93.104.2
0.debian.pool.ntp.org has address 213.141.154.170
0.debian.pool.ntp.org has address 46.254.216.9

За какой-нибудь да зацепится.

peerat
Offline
Зарегистрирован: 26.10.2015

вот так выглядит синхронизация через каждые 10 секунд  до ближайшего моего NTP:

IP:   192.168.1.40
GW:   192.168.1.1
DNS:  192.168.1.1
Mask: 255.255.255.0
DHCP: 0.0.0.0
NTP:  95.66.187.242
MAC:  0:1A:4B:38:C:5C
request sent
request sent
request sent
request sent
request sent
request sent
request sent
request sent
request sent
request sent
request sent
request sent
request sent
request sent
request sent
request sent
request sent
request sent
request sent
request sent
request sent
NTP time:
26/10/2015
21:33:06
request sent
NTP time:
26/10/2015
21:33:16
request sent
NTP time:
26/10/2015
21:33:26
request sent
NTP time:
26/10/2015
21:33:36
request sent
NTP time:
26/10/2015
21:33:46
request sent
NTP time:
26/10/2015
21:33:56
request sent
NTP time:
26/10/2015
21:34:06
request sent
NTP time:
26/10/2015
21:34:16
request sent
NTP time:
26/10/2015
21:34:26
request sent
NTP time:
26/10/2015
21:34:36

 

 

 

 
peerat
Offline
Зарегистрирован: 26.10.2015

Radjah пишет:

$host 0.debian.pool.ntp.org
0.debian.pool.ntp.org has address 46.46.152.214
0.debian.pool.ntp.org has address 188.93.104.2
0.debian.pool.ntp.org has address 213.141.154.170
0.debian.pool.ntp.org has address 46.254.216.9

За какой-нибудь да зацепится.

Из ваших самые короткие до меня это 1 и 3 по 4 мс.

Но к сожалению с ними синхронизироватся не удается...

peerat
Offline
Зарегистрирован: 26.10.2015

Удалось добится более менее стабильной синхронизации путемм ввода задержек и циклов. Теперь забирает время с большей части подсунутых для тестов NTP серверов но опять таки не с самого начала порядка 20 запросов уходят в пустоту, затем начинают идти ответы. Иногда так же возникают ситуации что ответы перестают на время доходить. В общем коряво пока, но синхронизация происходит.

модифицированный участок кода

 
int i = 0;
    while (i<3)
       {
       ether.ntpRequest(ntpServer, 0);
       int j = 0;
       while (j<10)
        {
        delay(7);
        ether.packetLoop(ether.packetReceive());
        if(ether.ntpProcessAnswer(&timeStamp, 0)) 
          {
          correctTime(timeStamp + 3600 * timeZone);
          syncStatusNTP = HIGH;
          }
        j++;
        }
       i++;
       }
       lastTimeSync = timeSync;