• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Вопрос NTPClient.h вопросы новичка

YaSerg

New member
Всем доброго времени суток!

Начинаю изучать работу со временем на ESP 8266, решил использовать встроенную, простенькую и мне понятную библиотеку NTPClient. Изучив стандартный пример из библиотеки возникло несколько вопросов:

Код:
#include <NTPClient.h>
// change next line to use with another board/shield
#include <ESP8266WiFi.h>
//#include <WiFi.h> // for WiFi shield
//#include <WiFi101.h> // for WiFi 101 shield or MKR1000
#include <WiFiUdp.h>

const char *ssid     = "<SSID>";
const char *password = "<PASSWORD>";

WiFiUDP ntpUDP;

// You can specify the time server pool and the offset (in seconds, can be
// changed later with setTimeOffset() ). Additionaly you can specify the
// update interval (in milliseconds, can be changed using setUpdateInterval() ).
NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000);

void setup(){
  Serial.begin(115200);

  WiFi.begin(ssid, password);

  while ( WiFi.status() != WL_CONNECTED ) {
    delay ( 500 );
    Serial.print ( "." );
  }

  timeClient.begin();
}

void loop() {
  timeClient.update();

  Serial.println(timeClient.getFormattedTime());

  delay(1000);
}
Строка 16 задает 1) сервер времени, 2) время сдвига как я понял это сдвиг для настройки часового пояса? 3) интервал синхронизации с сервером времени.
Верно интерпритирую?

Строка 32 выполняет синхронизацию с сервером времени если истекло время установленного интервала, который мы задавали в строке 16.
Верно интерпритирую?

Если я все верно понял есть следующий вопрос.
Можно ли в этой библиотеке понять когда была последняя синхронизация времени (на случай если интервал будет большой - сутки) или получить статус синхронизации (ок или ошибка)?

Всех заранее благодарю за уделенное внимание.
 

YaSerg

New member
Надеюсь это не снимает моего вопроса.
Обманулся этим постом #2

Пока игрался возник следующий вопрос, а можно ли получить время в другом формате например в миллисекундах с определенного момента?
 

Сергей_Ф

Moderator
Команда форума
@YaSerg вы сначала скажите, что за библиотеку вы используете, а потом уже вопросы задавайте. Извините, если звучит грубо. А то получается "раскажите мне то, не знаю что". То что у вас называется NTPClient.h может быть взято из сотни источников с совершенно разным функционалом.
 
Последнее редактирование:

YaSerg

New member
@YaSerg вы сначала скажите, что за библиотеку вы используете, а потом уже вопросы задавайте. Извините, если звучит грубо. А то получается "раскажите мне то, не знаю что". То что у вас называется NTPClient.h может быть взято из сотни источников с совершенно разным функционалом.
arduino-libraries/NTPClient
 

Сергей_Ф

Moderator
Команда форума
YaSerg, открываем NTPclient.h и видим
Код:
NTPClient(UDP& udp, const char* poolServerName, long timeOffset, unsigned long updateInterval);
Значит правильно интерпретируете.

Далее
Код:
 /**
     * This should be called in the main loop of your application. By default an update from the NTP Server is only
     * made every 60 seconds. This can be configured in the NTPClient constructor.
     *
     * @return true on success, false on failure
     */
    bool update();
Т.е. узнать что синхронизация прошла успешно можно, а вот когда - вряд-ли. Если не добавить новую функцию. Это всего три строки кода.

Ну и так далее. Там очень хорошее описание.
 
Последнее редактирование:

YaSerg

New member
Еще хотелось бы понимать как часто она обращается в сеть, меня немного волнует вопрос энергопотребления.

Как часто она обращается в сеть 1) при выполнении строки 32:
Код:
 timeClient.update();
или 2) раз в минуту, как указано в строках 15 и 16?
Код:
// update interval (in milliseconds, can be changed using setUpdateInterval() ).
NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000);
 

Сергей_Ф

Moderator
Команда форума
@YaSerg судя по коду обращается с интервалом, который установлен. По умолчанию раз в 60 секунд. Вы код смотрели? Там всё очень прозрачно и доступно даже для новичка. timeClient.update() только вызывает проверку на необходимость обновления.
 

Сергей_Ф

Moderator
Команда форума
можно ли получить время в другом формате например в миллисекундах с определенного момента?
Есть функция возвращающая время в секундах с 1 января 1970 года.
Код:
 /**
     * @return time in seconds since Jan. 1, 1970
     */
    unsigned long getEpochTime() const;
С миллисекундами через интернет оперировать как то не очень получается, да и не за чем.
 

YaSerg

New member
@YaSerg судя по коду обращается с интервалом, который установлен. По умолчанию раз в 60 секунд. Вы код смотрели? Там всё очень прозрачно и доступно даже для новичка. timeClient.update() только вызывает проверку на необходимость обновления.
К сожалению, мой уровень новичка пока не позволяет мне понимать код библиотек, извините (
Т.е. если в loop перестать выполнять проверку на необходимость обновления timeClient.update() то и запросы на NTP не будут проходить? В случае необходимости выполнить синхронизацию выполнить timeClient.update() и timeClient.getEpochTime() ?
 

Сергей_Ф

Moderator
Команда форума
если в loop перестать выполнять проверку на необходимость обновления timeClient.update() то и запросы на NTP не будут проходить?
Естественно.
В случае необходимости выполнить синхронизацию выполнить timeClient.update() и timeClient.getEpochTime() ?
Проверку надо делать в основном цикле, либо вручную принудительно синхронизировать через
Код:
 /**
     * This will force the update from the NTP Server.
     *
     * @return true on success, false on failure
     */
    bool forceUpdate();
.
А функция getEpochTime() возвращает число секунд с начала компьютерной эры, независимо от успешности текущей синхронизации. Естественно, хотя бы одна синхронизация должна быть выполнена перед этим.
Синхронизировать раз в минуту и даже в час смысла особого нет. Достаточно раз в сутки.
мой уровень новичка пока не позволяет мне понимать код библиотек,
Да полноте. Там всё написано на чистом английском языке. Там достаточно самых базовых знаний, если сам код не править.
И даже знаний английского не надо, если воспользоваться встроенным переводчиком в браузер.
 
Последнее редактирование:

selan61

Member
Здравствуйте все. Попробую обновить тему.
Сделал вайфай часы на Max7219 и ESP8266 с получением времени от NTP.
Использую эту же библиотеку.
Инициализирую NTPClient timeClient(ntpUDP,“europe.pool.ntp.org”,14400,60000);
То есть опрос сервера NTP раз в минуту

Раз в минуту вывожу бегущей строкой день недели и дату с годом, или температуру в доме и на улице.
Раз в 5 минут получаю и парсю температуры со своего уличного датчика на народном мониторинге
Раз в секунду с помощью SimpleTimer получаю время от библиотеки и вывожу на экран

Если оставить только работу с временем, то получится такой код
Код:
#include <ESP8266WiFi.h>
#include <NTPClient.h>
#include <WiFiUdp.h> 
//**************************************************************
//const char* ssid     = "";     // название и пароль точки доступа
const char* ssid     = "";
const char* password = "";
const char* host     = "narodmon.ru";
const int   httpPort = 8283;
//**************************************************************
#define t0_interval          1000          // через время (1*1000) милисекунд многократно выполнять функцию DisplayTime
#define t2_interval        300000          // через время (5*60*1000) милисекунд многократно выполнять функцию jsonGet
//**************************************************************
int day,dd,hh,mm,ss;                       // день,дата,час,мин,сек
String Date = "";
String Time = "";
unsigned int timer0, timer1, timer2;
//**************************************************************
WiFiUDP ntpUDP;
SimpleTimer timer;
NTPClient timeClient(ntpUDP, "europe.pool.ntp.org",14400,60000); // 14400 - временной сдвиг в секундах от UTC и период опроса
//**************************************************************
void setup(){
// Запускаем WIFI                             
      ConnectWiFi();

// Запускаем NTPClient 
    timeClient.begin();

// Запускаем таймеры
    timer0 = timer.setInterval(t0_interval, DisplayTime);
    timer2 = timer.setInterval(t2_interval, jsonGet);     
}
//**************************************************************
// Бегущая строка
void Scroll(){
// Получение текущего времени
    Time_init();   

// запускаем бегущую строку
    if(FLAG){  // выводим дни недели.....
       }
    else {   // температура в доме и на улице
         }
  
 FLAG = !FLAG;
    DisplayTime();
}
//**************************************************************
void loop(){
    timer.run();
    timeClient.update();
    yield();
}
//**************************************************************
// Получаем текущее время и день недели
void DisplayTime(){
     timeClient.update();
    hh = timeClient.getHours();
    mm = timeClient.getMinutes();
    ss = timeClient.getSeconds();
   day = timeClient.getDay();

// Определяем момент для бегущей строки
  if(ss == 0) Scroll();

// Выводим время на Max7219   
    matrix.fillScreen(LOW);
..............................
..............................
}
//**************************************************************
void Time_init(){
// Получение текущего времени
    timeClient.update();
     Time = String(timeClient.getFormattedTime());
     String date_time = timeClient.getFormattedDate();
     Date = date_time.substring(0, 10);
// выводим в  Serial
     Serial.println(Time);
     WebSerial.print(hh);  WebSerial.print(":");  WebSerial.print(mm);
     WebSerial.print(":"); WebSerial.println(ss);
     WebSerial.println(date_time);
}
//**************************************************************
void jsonGet(){
// Получаем температуру из сети и в доме
}
//END***********************************************************
Всё работает отлично, если бы не периодическое отставание до 5 минут с последующим восстановление точного времени.
Один раз минуты совпали, но часы отставали на час. Вывел информацию о полученном времени раз минуту в WebSerial для контроля.
Так по нему получается, что такое отстающее время я получаю от библиотеки. Однако после перезагрузки время восстанавливается.
Что то я совсем ничего не понимаю. Даже если не правильное время даст библиотека, то раз в минуту она получает реальное время от NTP. То есть, если в секундах она сбилась, то через минуту время должно восстановиться, однако этого не происходит. Может разъясните в чем я ошибаюсь?
 

Сергей_Ф

Moderator
Команда форума

selan61

Member
Это функция получения времени от библиотеки. Код сокращённый, в котором просто показано как я получаю время. Основан на стандартном примере библиотеки, просто delay заменён на SimpleTimer. Период обновления также стандартный для этой библиотеки. Согласно ее описания.
 

selan61

Member
Нашел такую тему Время по NTP (UDP) Оказывается, дело не в библиотеке, а в сбоях Udp запросов. Проблему в основном понял. буду дальше разбираться.
 

selan61

Member
Обязательно, но завтра. Уехал из деревни в город. Вернусь поздно.
Кстати, нашел такую библиотеку ESPNtpClient
Автор пишет, что управление временем
осуществляется подсистемой времени Espressif sdk
Надо будет попробовать.
 
Сверху Снизу