• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

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

unreg

Member
Всем привет! Необходимо на устройстве поддерживать относительно точное время посредством NTP. Само устройство на базе esp32 (библа v 1.0.6). Работаю через configTime, getLocalTime (Arduino.h) getLocalTime обеспечивает блокировку основного цикла, я так понял от того, что "ждет" результата ntp, и ждет его в цикле по времени да еще и с delay внутри. Может где-то есть готовая асинхронная реализация? Можно наверное и самому сгородить по проверке на валидность даты, но все таки от запроса было бы правильнее имхо
 

Сергей_Ф

Moderator
Команда форума
ну так не ждите. В чем проблема? Время выставиться, если time(nullptr) возвратит что-то похожее на реальное время. Но нужно ли вам работать с неустановленным временем?
 

unreg

Member
это мой запасной аэродром. Я так и написал "...Можно наверное и самому сгородить по проверке на валидность даты..." Вопрос был: есть ли готова... да, короче, читайте до конца. На последние два предложения сил не хватило? ) По существу - может работать и с неустановленным, но с ограниченным функционалом
 

Сергей_Ф

Moderator
Команда форума
На последние два предложения сил не хватило?
Хватило. А вам не хватило сил посмотреть реализацию time.h на предмет наличия там валидатора?
Вы же сишный файл посмотрели, вроде, зачем спрашивать очевидные вещи? Нашли там валидатор?
 
Последнее редактирование:

unreg

Member
Есть, что сказать по существу, или будете мои слова повторять и сыпать терминами?
 

unreg

Member
подпилил официальный пример asyncudpclient. сутки погонял - точность сохраняется в пределах секунды. оставлю тут, авось пригодится тем кто не знает где искать валидатор
C++:
#include "Arduino.h"
#include "WiFi.h"
#include "AsyncUDP.h"

#define secs70 2208988800UL
#define NTP_PACKET_SIZE 48
#define UPDATE_PERIOD 10 //каждый 10 сек корректируем время

unsigned long lastUpdate = 0;
long          gmtOffset = 3600 * 9; //9 - мой часовой пояс
unsigned long offsetTime = 0;
unsigned long updateT = 0;

int retryUpd = 0;


time_t now; //системное время на устройстве

const char* ssid = "ssid";
const char* password = "pass";

AsyncUDP udp;

void setup()
{
    Serial.begin(115200);
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);
    if (WiFi.waitForConnectResult() != WL_CONNECTED) {
        Serial.println("WiFi Failed");
        while (1) {
            delay(1000);
        }
    }

    now = millis() / 1000;

    if (udp.connect(IPAddress(162, 159, 200, 123), 123)) //time.cloudflare.com......pool.ntp.org 0-й сервер (197,84,150,123)/*
    {
        Serial.println("UDP connected");

        udp.onPacket([](AsyncUDPPacket packet)
            {
                unsigned long highWord = word(packet.data()[40], packet.data()[41]);
                unsigned long lowWord = word(packet.data()[42], packet.data()[43]);

                unsigned long secs1900 = highWord << 16 | lowWord;

                unsigned long current = secs1900 - secs70 + gmtOffset;

                offsetTime = (time_t)(current);
                
                Serial.println("TIME CORRECTION");
            });       
    }
}

void printTime()
{
    tm tm;
    localtime_r(&now, &tm);

    char buff[30];

    strftime(buff, 256, "%Y-%m-%d  %H:%M:%S", &tm);
    Serial.println(buff);
}

void update() {
    byte buff[NTP_PACKET_SIZE]; //48
    memset(buff, 0, NTP_PACKET_SIZE);
    
    buff[0] = 0b11100011;   
    buff[1] = 0;
    buff[2] = 6;
    buff[3] = 0xEC;
    buff[12] = 49;
    buff[13] = 0x4E;
    buff[14] = 49;
    buff[15] = 52;

    if (udp.connected())
        udp.write(buff, NTP_PACKET_SIZE);
}

void loop()
{
    now = offsetTime + (millis() - updateT) / 1000;
      
    if (millis() - lastUpdate > 1000)
    {
        Serial.print("Now: ");
        printTime();
        lastUpdate = millis();
        retryUpd++;
        if (retryUpd >= UPDATE_PERIOD)//~каждые 10 секунд корректировка асинхронная
        {
            updateT = millis();
            update();
            retryUpd = 0;
        }
    }
}
 

tcl43p637

New member
Накатал библиотеку по мотивам исходника выше, может кому надо:
 

Вложения

Сверху Снизу