синхронизация времени c NTP
- Войдите на сайт для отправки комментариев
Добрый день! Уже несколько дней бьюсь над вопросом синхронизации времени от 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));
}
строка 15 ваш днс сервер где?, лучше определять по имени а не по ip
попробовать с компа пропинговать ntp сервера
почему это лучше определять по имени?
NTP сервера пингуются
За какой-нибудь да зацепится.
вот так выглядит синхронизация через каждые 10 секунд до ближайшего моего NTP:
За какой-нибудь да зацепится.
Из ваших самые короткие до меня это 1 и 3 по 4 мс.
Но к сожалению с ними синхронизироватся не удается...
Удалось добится более менее стабильной синхронизации путемм ввода задержек и циклов. Теперь забирает время с большей части подсунутых для тестов 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;