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

Как задать локальное время без модуля и NTP-Сервера?

Andrey L

Member
Хочу обработать сценарий, когда модуль не сможет связаться с NTP-Сервером, т.е. установить вручную "локальное время". (Если модуль получает доступ к интернету, а следовательно к NTP-Серверу, то всё работает нормально.)

Экспериментирую с NodeMcu и "Arduino IDE".

Подключил библиотеку "time.h" (#include <time.h>).

В файле ...arduino-1.8.8\hardware\tools\avr\avr\include\time.h нашёл функцию "void set_sytem_time(time_t timestamp);" (Строчка 302). Как я понял, эта функция и задаёт "локальное время".

Но вот код не компилируется
Код:
// Выше пытаюсь подключиться к NTP-серверу при помощи configTime()

time_t now = time(nullptr);
set_system_time(now);
Выдаётся ошибка "'set_system_time' was not declared in this scope".


Может быть кто-то подскажет как выставить это локальное время?
Или хотя бы скажите, что я не так делаю?
 

Юрий Ботов

Moderator
Команда форума
А что вы понимаете под "локальным временем"? Процессор не хранит в состоянии сна или отключения время. В любом случае нужен источник времени: NTP, модуль RTC или на худой конец ввод руками через терминал как это было в первых IBM PC/XT.
 

Andrey L

Member
@Andrey L библиотека для AVR, а компилируете для esp8266
Ага, вот только больше никаких "time.h" у себя на компе не нашёл.

Где мне тогда описание библиотек искать?
Залез на github, нашёл файл esp8266/Arduino - это то? Только вот коментарий рядом с декларациями функций я не нашёл.

Но главный вопрос остаётся: А как же правильно сделать?
 

Andrey L

Member
А что вы понимаете под "локальным временем"? Процессор не хранит в состоянии сна или отключения время. В любом случае нужен источник времени: NTP, модуль RTC или на худой конец ввод руками через терминал как это было в первых IBM PC/XT.
Да, при включении ручками вводить примерное нынешнее время. (Плюс-мину час меня вполне устроит.)

Мой модуль не будет выключаться.

А вот тема "сна" может оказаться решающей, но я хотел всё решать по очереди. (Прежде чем взобраться на гору, я хотел взойти на холм, который находится по дороге к ней.)
 

Юрий Ботов

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

Andrey L

Member
Может все таки RTC поставить - вещь копеешная... и кучу проблем снимет. Такой Часы реального времени RTC DS1307 (модуль) или с Али - там разных полно.
Спасибо за совет, но мне всё-таки хочется без дополнительных модулей.

Вдруг это возможно, если модуль в режим "сна" не вводить и не выключать.
 

nikolz

Well-known member
Спасибо за совет, но мне всё-таки хочется без дополнительных модулей.

Вдруг это возможно, если модуль в режим "сна" не вводить и не выключать.
все возможно
даже в режиме сна
так как во сне работает RTC ESP и отсчитывает время сна. Поэтому можно хранить время и корректировать его на время сна
при просыпании ходить на сервер времени и корректировать по нему
еще можно подключить GPS
Сервер очень точного времени stratum 1 на Garmin GPS
 

Andrey L

Member
все возможно
даже в режиме сна
так как во сне работает RTC ESP и отсчитывает время сна. Поэтому можно хранить время и корректировать его на время сна
при просыпании ходить на сервер времени и корректировать по нему
еще можно подключить GPS
Сервер очень точного времени stratum 1 на Garmin GPS
Очень благодарен, а можете ещё объяснить как "можно хранить время"?
 

Сергей_Ф

Moderator
Команда форума
@Andrey L перед уходом ко сну запишите время в RTC-память. Усните, когда проснетесь прочитайте время из RTC--памяти и добавьте то время, на которое уснули. Вы же его знаете. Как то так.
 

Andrey L

Member
@Andrey L перед уходом ко сну запишите время в RTC-память. Усните, когда проснетесь прочитайте время из RTC--памяти и добавьте то время, на которое уснули. Вы же его знаете. Как то так.
Вот я и спрашиваю, как записать время.
 

Andrey L

Member
@Andrey L посмотрите два примера в Ардуино IDE ESP8266\NTP-TZ-DST и RTCUserMemory. Возможно это поможет.
Благодаря Вашей наводке на ESP8266\NTP-TZ-DST нашёл функцию settimeofday() из библиотеки "sys/time.h".


Код:
// Выше идёт инициализация и прочая настройка

time_t now = time(nullptr);
// добавляет к "нынешнему" времени почти 10 лет, нельзя о високосных годах забывать
now += 60*60*24*365*10;
// тут шаману нельзя мешать танцевать с бубном
timeval tv = { now, 0 };
timezone tz = { 0, 0 };
settimeofday(&tv, &tz);

// ниже time(nullptr) выдаёт дату уже со сдвигом на почти 10 лет.
Сейчас буду искать как struct tm превратить в time_t, а то не удобно с time_t напрямую работать.
 

Andrey L

Member
Время уже позднее...
Код:
#include <time.h>
#include <sys/time.h>

// Тут идут настройки

time_t now = time(nullptr);

//Со struct tm удобней работать чем с time_t
tm* newTime = localtime(&now);
newTime->tm_hour=0; //Ноль часов
newTime->tm_year=110; //2010-го года (=1900+110)

// Превращаем обратно struct tm в time_t
now = mktime(newTime);
// А теперь магические строчки, ради которых я и создал эту тему
timeval tv = { now, 0 };
timezone tz = { 0, 0 };
settimeofday(&tv, &tz);
Документацию бы ещё settimeofday() добыть, тогда было бы хорошо.
 

nikolz

Well-known member
Вот я и спрашиваю, как записать время.
ESP8266:Прошивки/Arduino/Библиотеки для работы с аддоном ESP8266 для IDE Arduino — Онлайн справочник
--------------------
Функции ESP.rtcUserMemoryWrite(offset, &data, sizeof(data)) и ESP.rtcUserMemoryRead(offset, &data, sizeof(data)) позволяют записывать и считывать данные из пользовательской RTC-памяти ESP8266. Общий размер пользовательской RTC-памяти чипа составляет 512 байт, поэтому сумма значений в аргументах offset и sizeof(data) не должна превышать «512». Данные должны быть выровнены под 4 байта. Сохраненные данные могут быть считаны между циклами спящего режима. Впрочем, из-за включения/выключения ESP8266 данные могут быть утеряны
--------------------
Если надо сохранить структуру, то пишите ее в RTC. Если в ней есть указатели, то пишите то, на что они указывают в RTC.
после просыпания читаете в обратном порядке.
 

AlexKont

New member
Время уже позднее...
Код:
#include <time.h>
#include <sys/time.h>

// Тут идут настройки

time_t now = time(nullptr);

//Со struct tm удобней работать чем с time_t
tm* newTime = localtime(&now);
newTime->tm_hour=0; //Ноль часов
newTime->tm_year=110; //2010-го года (=1900+110)

// Превращаем обратно struct tm в time_t
now = mktime(newTime);
// А теперь магические строчки, ради которых я и создал эту тему
timeval tv = { now, 0 };
timezone tz = { 0, 0 };
settimeofday(&tv, &tz);
Документацию бы ещё settimeofday() добыть, тогда было бы хорошо.
Все для ESP32 там: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/system_time.html
 

enjoynering

Well-known member
Сейчас у меня на базе этого примера часы сделаны. Получаю время по NTP 3-я!!! строчками кода.
 

AlexKont

New member
Сейчас у меня на базе этого примера часы сделаны. Получаю время по NTP 3-я!!! строчками кода.
Замечательно! Если не считать строки объявлений, то нужно всего две функции "библии" : configTime() и getLocalTime(). Тут и дата, тут и время.
Ну, а кому нужно "поковыряться" внутри "вселенной времени", в помощь: gettimeofday(), settimeofday() с их timeval и timezone, и весь набор API Ref...
А так верно, GitHub Всем в помощь! ;)
 
Сверху Снизу