• Система автоматизации с открытым исходным кодом на базе 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
Накатал библиотеку по мотивам исходника выше, может кому надо:
 

Вложения

Сверху Снизу