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

Делюсь опытом Вот написал классик для NTP

Sr.FatCat

Member
Получение точного времени, не знаю у кого как - у меня процедура частая.

Вот написал класс, слепив разное из примеров, так как удобно пользоваться мне. Может кому еще пригодится.

Плюсы: Предельно простое использование (описание, init, get). Не нужны переменные для хранения даты-времени. Предопределены хорошие NTP сервера, по IP. Не болтается громодкая TimeLib.h в основном скетче. При слишком частом вызове, используется millis для ответа. Плохо ответивший сервер помещается вниз. Все настройки разным вызовом конструкторов.

Критика или советы по переделке - категорически приветствуются.
 

Вложения

Сергей_Ф

Moderator
Команда форума
@Sr.FatCat не плохо, но нигде кроме России эту библиотеку использовать не удасться. Нет перевода зимнего и летнего времени, да и 12-часового формата, вроде тоже.
и вот тут
Код:
//        CNTPTime ntpTime((uint8_t) 5, new new IPAddress(88, 147, 254, 232));
наверное ошибка. Зачем два раза new ?
 

Sr.FatCat

Member
@Сергей_Ф, в комментариях конечно очепятка. Одного new больше чем достаточно :)
Я не задумывал это как библиотеку, поэтому даже не думал, про что-то, кроме наших реалий. Добавить 12 часовой формат, это 5 минут - но кому он нужен? Только Америка? Добавлять зимнее-летнее время, тоже можно, но класс подрастет в объеме изрядно. Считаете имеет смысл?
 

Сергей_Ф

Moderator
Команда форума
@Sr.FatCat если уж выкладываете, то нужно делать до конца. Мне 12-ти часовой режим не нужен, но... мало ли. Зимнее и летнее время нужно 100%, оно есть в большинстве стран. До определенного момента, тоже мне не нужно было. Но выход на международный рынок, даже малюсенький, требует наличие летнего времени.
Кстати, не слишком ли мал период для повторного обращения к серверам времени? Мне кажется раз в 6 и даже 12 часов, вполне достаточно. Остальное можно и через millis получать. Хотя это настраиваемо, так что не критично.
 
Последнее редактирование:

Юрий Ботов

Moderator
Команда форума
Добавлять зимнее-летнее время, тоже можно, но класс подрастет в объеме изрядно.
Есть такая штука - define, ifndef, ifdef... как раз для таких случаев: собираете то что вам надо и даете другим возможность скомпилить в их версии необходимые возможности.
 

Sr.FatCat

Member
@Сергей_Ф, я выложил -именно тот минимальный функционал, который написал лично для себя, в надежде, что кому-то он может пригодится. Сама по себе вещь, на мой взгляд,, функционально законченная, хотя с ограниченниями. Будет время - обязательно учту Ваши пожелания.

Что касается частоты запросов - я вообще планировал - вычислять после каждого расхождение с полученными по millis и в зависимости от этого увеличивать интеллектуально или уменьшать интервал обращений. Но что-то алгоритм изменения не придумывается. В голову приходит только половинное увеличение/уменьшение - но как-то из пальца это высосано, а сидеть с кучей ESP и проверять как это будет работать - что-то не очень охота.

@Юрий Ботов, спасибо - я знаком с препроцессором немного. Если бы можно было в скетче указать #define SUMMER_TIME и чтобы библиотека (т.е. .cpp, а не .h) это увидела, было бы красиво. А так придется диррективы править в .h, что уже как-то и не совсем красиво. Да и насколько я понимаю, может казус получиться, когда .h поправишь, а библиотека не будет перекомпилирована и ошибка выскочит уже на стадии линковки. Вы правы, в том случае, если всегда используешь библиотеку с одной диррективой, а не в одном скетче одно, в другом - другое.
 

pvvx

Активный участник сообщества
Вы уверены, что UDP запрос с вашим "полингом" дойдет за 150*15 ms в случае прохождения соединения через GSM? :)
(В России задерки при инете через GSM проскакивают до 5 секунд)
И вообще - в ESP8266 нет RTOS и ваш циклический "полинг" отнимает ресурсы (время) у основной программы.
Организуйте алгоритм работы по событиям, а не в цикле.
Тем более в SDK уже есть SNTP сервер.
Espressif\ESP8266_SDK\include\sntp.h
 
Последнее редактирование:

Сергей_Ф

Moderator
Команда форума
Если бы можно было в скетче указать #define SUMMER_TIME и чтобы библиотека (т.е. .cpp, а не .h) это увидела, было бы красиво.
А почему Вы считаете, что так нельзя?
Обьявляйте SUMMER_TIME в программе, а в .h определяйте #ifdef SUMMER_TIME
#define _SUMMER_TIME_

и будет все в .cpp
 

pvvx

Активный участник сообщества
Да, и не забудьте согласовать SNTP с DHCP. В местной интрасети может быть местный NTP... :)
Удачи на Arduno... ;)
extern "C" {
#include "sntp.h"
}
 

Sr.FatCat

Member
@Сергей_Ф, ну как бы .cpp компилируется, не зная, что вообще скетч существует. Разве нет? И он подключая .h файл - всегда будет видеть SUMMER_TIME неопределенным
 

Sr.FatCat

Member
Вы уверены, что UDP запрос с вашим "полингом" дойдет за 150*15 ms в случае прохождения соединения через GSM? :)
(В России задерки при инете через GSM проскакивают до 5 секунд)
Вообще не уверен. Да и не понятна задача. Если подключение идет через GSM модем, то правильнее, я считаю, время синхрить по времени GSM сети. Если подключение идет через GSM роутер, то - да могут быть проблемы. Задачи "учесть
все на свете" - у меня вообще не стояло. Но я постараюсь учесть, если буду править дальше.
И вообще - в ESP8266 нет RTOS и ваш циклический "полинг" отнимает ресурсы (время) у основной программы.
Организуйте алгоритм работы по событиям, а не в цикле.
Это вообще о чем? О примере? ;) В реальной программе я естественно работаю по событиям. И вызов getTime у меня может быть вообще один на сессию :) Какое это отношение имеет к классу?
Тем более в SDK уже есть SNTP сервер.
Espressif\ESP8266_SDK\include\sntp.h
Вы уверены, что подкючение sntp.h и вызов sntp_get_current_timestamp() более оправдано по ресурсам, чем самостоятельный udp запрос? Но все равно спасибо за наколку - будет время - проверю, что лучше.

Удачи на Arduno... ;)
extern "C" {
#include "sntp.h"
}
Это к чему? Хорошие люди не пишут на паскале под Arduino IDE? Так, я и не против. Каждый выбирает сам, надо ему лопатить тонны документации и помнить все регистры и микросекунды выполнения операция, пользоваться ли сторонними СДК или писать высокоровневых надстройках типа Wire. Я себя ущербным не чувствую, когда digitalWrite пишу :))))))
 

Сергей_Ф

Moderator
Команда форума
@Sr.FatCat так я написал, как сделать. Определите в заголовке новый _SUMMER_TIME_ ,с подчеркиваниями, в зависимости от основного. Его cpp легко увидит, поскольку свой заголовок он всегда подключает.
 

Sr.FatCat

Member
@Сергей_Ф, может я туплю, но компилируются .ino и .cpp отдельно вроде. И когда будет компилироваться .cpp он конечно подключит .h, но _SUMMER_TIME_ в нем не будет зависить от SUMMER_TIME в ino. Разве нет?
 

pvvx

Активный участник сообщества
Вы уверены, что подкючение sntp.h и вызов sntp_get_current_timestamp() более оправдано по ресурсам, чем самостоятельный udp запрос?
По ресурсам - получше, т.к. нет циклов, отнимающих время работы основной программы. И опрос там ведется через dns по списку серверов. Это стандартный пример взятый из библиотеки к LwIP.
Каждый выбирает сам, надо ему лопатить тонны документации и помнить все регистры и микросекунды выполнения операция, пользоваться ли сторонними СДК или писать высокоровневых надстройках типа Wire. Я себя ущербным не чувствую, когда digitalWrite пишу :))))))
Да, я понимаю ваши проблемы с "лопаченеим тонн документации", возникшие от использования языков высокого уровня. Там без знания сотен подключаемых библиотек и тысяч их процедур ничего не сделать. :)
Нашел, что такое digitalWrite() - а как оно в многозадачке себя поведет? Кто владелец ресурса пинов (?), а то одна задача включит режим вывода, а другая ввод для пина... Особо актуально при использовании выводов как разные сигналы к внешним устройствам и их совмещении... Пин то не многопользовательский (не разделяемый ресурс) :)
PS: У вас странное отношение – синхронизация системного времени является системной задачей, а не пользовательской. Написание надстроек актуально для процесса изучения работы инет, и в целях обучение всегда приветствуется.
PS2: А чем так провинился 'паскаль'? У каждого языка своя область актуальности. Вопрос интересен, т.к. многие развязывают религиозные войны из-за незнания разных языков и областей их применимости...
ЗЫ3Ж В Arduino очень много примеров и библиотек работающих в циклическом опросе, без какой либо синхронизации. Этим оно мне не нравиться, т.к. всегда приходится переписывать практически все работающие с внешними устройствами библиотеки на обработку по событиям, обычно по аппаратным прерываниям, чтобы получить синхронный поток данных с возможностями дальнейшей обработки (особо актуально при дальнейшей фильтрации). Это накладывает ограничения на использование Arduino. С ростом производительности и ресурсов у MCU для работы в многопоточных режимах Arduino отстает от паровоза, т.к. необходимо многие функции в ней менять и вообще заменять на другой подход...
 
Последнее редактирование:

Сергей_Ф

Moderator
Команда форума
@Sr.FatCat Вы правы, это я ступил. Действительно, то что определено с условиями в заголовке класса, зависящими от определений в основной программе ino, не проходит в cpp. Что удивительно, оно проходит в основную программу ino. А поскольку я всегда использовал определения из заголовка класса в качестве аргументов для вызова конструктора класса, был уверен, что они попадают и в конструктор на cpp. Оказывается нет. Надо искать другой путь.
Вы вроде бы просили критику и пожелания, а сейчас все предложения встречаете "в штыки". Делать или нет - решать, безусловно, Вам. Отнеситесь к этому философски :).
 

Сергей_Ф

Moderator
Команда форума
синхронизация системного времени является системной задачей, а не пользовательской.
Подскажите, пожалуйста, в sntp.h реализован механизм учета перехода на летнее время? И это задача системная или позьзовательская?
 

pvvx

Активный участник сообщества
Подскажите, пожалуйста, в sntp.h реализован механизм учета перехода на летнее время? И это задача системная или позьзовательская?
Это не исполняемая для современных процессоров задача. Время перехода на летнее время зависит от местной исполнительной власти региона и ни как не кореллируется ни с чем. В году может быть более нескольких переходов на летнее время, а процессоры не ещё умеют определять указы местных властей.
Я думаю, что Arduino тут точно не подойдет. Для решения данной задачи по территории России необходимо использовать какой-то квантовый компьютер с десятками кубитов...
Когда делали голосовой гит для Авто с подробными картами России мы с этой задачей не справились... :( Т.е. имея точную GPS координату, GSM связь и подробные карты не смогли задать региональные гуляющие-границы текущего там времени. В каждом селе оно своё, а так-же как решат местные... вчера так- завтра по другому, как больше им подходит :)
 
Последнее редактирование:

Сергей_Ф

Moderator
Команда форума
@pvvx Но ведь все компьютеры и смартфоны как то с этой задачей справляются? А даты перехода, вроде определены достаточно определенно. В России, так вообще нет сейчас перехода, так что квантовый компьютер точно не потребуется :)
Вы случайно с часовым поясом не перепутали?
 

pvvx

Активный участник сообщества
@pvvx Но ведь все компьютеры и смартфоны как то с этой задачей справляются? А даты перехода, вроде определены достаточно определенно. В России, так вообще нет сейчас перехода, так что квантовый компьютер точно не потребуется :)
Вы случайно с часовым поясом не перепутали?
Ничего не перепутал. Решение одно - оставляете смещение времени от GPS или GTM на выбор пользователя.
И комп и телефон у меня с данной задачей не справляются. Один старый телефон по несколько раз переводит время - по своему зашитому алго и команде с GSM. :)
 
Последнее редактирование:

Sr.FatCat

Member
@Сергей_Ф, я не в штыки, я просто дискутирую про необходимость той или иной функциональности. Мне ясен ваш интерес и я пытаюсь понять его "глобальность". Никакого негатива с моей стороны нет :) Спасибо Вам за комментарии и спасибо @pvvx за идею с sntp.h
Кстати sntp_get_current_timestamp() из sntp.h возвращает тоже юниксовское время, которое потом разбирать еще надо (т.е. тоже в рамках функциональности моего класса) на дату/время. А автоматический переход на зимнее/летнее время наверное можно реализовать, если иметь надежный ресурс этих данных. Вот здесь вроде калькулятор для Европы и Штатов до 2099 года. Ну или просто добавить в класс две настраиваемые даты перехода и оставить на усмотрение создателя экземпляра.

@pvvx, "Хорошие люди не пишут на паскале" это мем из безсмертного произведения времен фидо "9600 бод и все, все, все...". Классику хорошо бы помнить;) И это как-бы намекает, что Assm VS С++, и прочие холивары решения задач разноуровневых языков имеют корни столь же древние, как и сами языки. Поэтому с Arduino IDE у меня удачи не меньше, чем у вас с нативными библиотеками, по-крайней мере, все мои поделухи, некоторые довольно не просты, работают на Arduino вполне хорошо и мне это не потребовало детального изучения даташитов . Да и, что такое многозадачность на однопоточном/однокристальном МК, а так же, какой еще там владелец - моему понятию недоступно. Если мне надо, чтобы одна задача гарантировано не мешала выполнению другой и временным разделением это не решить, я просто меняю топологию девайса и разношу задачи по разным МК.
 
Последнее редактирование:
Сверху Снизу