В состав ESP32 входит два аппаратных таймера, которые могут использоваться для отслеживания системного времени в зависимости от назначения приложения и требований к точности системного времени:
Таймер RTC: этот таймер позволяет отслеживать время в различных режимах сна, а также сохранять время при любых сбросах (за исключением сбросов при включении питания, которые сбрасывают таймер RTC). Отклонение частоты зависит от источников тактового сигнала таймера RTC и влияет на точность только в режимах сна, в этом случае время будет измеряться с разрешением 6,6667 мкс.
Таймер с высоким разрешением: этот таймер недоступен в спящих режимах и не сохраняется после сброса, но обладает большей точностью. Таймер использует источник тактовых импульсов APB_CLK (обычно 80 МГц), отклонение частоты которого составляет менее ±10 частей на миллион. Время будет измеряться с точностью до 1 мкс.
По умолчанию, для синхронизации системного времени используется комбинация обоих таймеров - RTC и высокого разрешения .
Частотную работу таймера RTC обеспечивает одно из возможных устройств: два внутренних (встроенных) и два внешних. По умолчанию используется Internal 150 kHz RC oscillator . Он обеспечивает минимальное потребление тока в режиме глубокого сна и не зависит от каких-либо внешних компонентов. Однако на стабильность частоты этого источника тактового сигнала влияют колебания температуры, поэтому время может смещаться как в режиме глубокого сна, так и в режиме лёгкого сна.
Второй внутренний таймер, который может использоваться, Internal 8.5 MHz oscillator, divided by 256 (about 33 kHz). Этот таймер обеспечивает более высокую стабильность частоты, чем Internal 150 kHz RC oscillator за счет более высокого (на 5 мкА) потребления тока в глубоком режиме сна.
И может быть подключен один из двух внешних таймеров: External 32 kHz crystal или External 32 kHz oscillator at 32K_XN pin.
После включения питания ESP32 начинает отсчитывать время в секундах “с начала эпохи” - 1 января 1900 года. Для того, чтобы прочитать время таймера платы, можно воспользоваться командой - gettimeofday(). Для немедленного обновления текущего времени используется функция settimeofday().
Формат команд gettimeofday(), settimeofday() идентичный:
int gettimeofday (struct timeval *tp, struct timezone *tzp);
int settimeofday (struct timeval *tp, struct timezone *tzp)
Функция gettimeofday() получает, а функция settimeofday() устанавливает в системе представление о текущем времени. Текущее время выражается в секундах и микросекундах, прошедших по всемирному координированному времени с 00:00:00 (часов,минут,секунд) 1 января 1970 года.
Аргумент tp указывает на структуру timeval, которая включает в себя следующие элементы:
struct timeval
{
long tv_sec; /* секунды с 1 января 1970 года */
long tv_usec; /* и микросекунды */
};
Аргумент tzp содержит информацию о часовом поясе. См. TIMEZONE, но в gettimeofday() и settimeofday() аргумент tzp игнорируется.
Если требуется узнать прошедшее время с начала эпохи с точностью до одной микросекунды, воспользуйтесь приведённым ниже фрагментом кода:
struct timeval tv_now;
gettimeofday(&tv_now, NULL);
int64_t time_us = (int64_t)tv_now.tv_sec * 1000000L + (int64_t)tv_now.tv_usec;
Если нужно получить время с точностью до секунды, используйте следующий фрагмент кода:
time_t now;
char strftime_buf[64];
struct tm timeinfo;
// Выбираем текущее время
time(&now);
// Устанавливаем стандартное время для региона - Европа/Москва
// https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv
setenv("TZ", "MSK-3", 1);
tzset();
localtime_r(&now, &timeinfo);
strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);
printf("Текущие дата и время в Петрозаводске: %s\n", strftime_buf);
Так как в программном обеспечении контроллера (и в показанном фрагменте) время представляется в формате UTC, то для настройки Esp32 следует правильно установить часовой пояс. Например, для использования австралийского восточного стандартного времени (AEST) с учетом перехода на летнее время следует указать - «AEST-10AEDT,M10.1.0,M4.1.0/3».
Части этого определения часового пояса следующие:
Чтобы узнать о других определениях часовых поясов, обратитесь к базе данных часовых поясов Posix.
Форматирование данных о текущем времени при выводе выполняется с помощью структуры данных - struct tm и по правилам для функции strftime() - format time as string.
"%A, %B %d %Y %H:%M:%S" - это спецификаторы формата, которые определяют, как
в struct tm timeinfo; будет отформатирован текст, а члены tm struct следующие:
Тип элемента Значение Диапазон
-----------------------------------------------------
tm_sec int секунды после минуты 0-61*
tm_min int минуты после часа 0-59
tm_hour int часы с полуночи 0-23
tm_mday int день месяца 1-31
tm_mon int месяцы с января 0-11
tm_year int годы с 1900
tm_wday — количество дней с воскресенья 0-6
tm_yday — количество дней с 1 января 0-365
tm_isdst — флаг перехода на летнее время
NTP расшифровывается как «протокол сетевого времени», а сервер NTP — это специализированная компьютерная система, которая предоставляет точную информацию о времени для других интернет-устройств.
Клиент NTP регулярно опрашивает один или несколько серверов NTP, чтобы получить текущее время, и синхронизирует свои внутренние часы на основе полученной метки времени. ESP32 так же в качестве клиента ESP32 подключается через маршрутизатор и Wi-Fi к интернету, и инициирует подключение к пулу серверов NTP. Один из серверов NTP отвечает меткой времени, которую получает ESP32 и использует для настройки своих внутренних часов.

Сами серверы NTP организованы в иерархическую многоуровневую систему с высокоточными устройствами для измерения времени, такими как атомные часы, GNSS (включая GPS) или другие радиочасы (авторитетные источники времени). Отдельные уровни называются стратами.

Как правило, устройства подключаются не к конкретному серверу NTP (IP-адресу), а к пулу второго или третьего страта из множества серверов NTP.
Пул NTP — это динамическая коллекция сетевых серверов NTP. В следующей таблице показано количество серверов NTP в пуле ntp.org в разных географических регионах.

Пул серверов MSK-IX NTP Server: ntp.msk-ix.ru реализован в виде группировки серверов, размещенных в Москве, Санкт-Петербурге, Екатеринбурге и Новосибирске, и относится к высшему уровню точности (Stratum One Time Servers) в иерархической системе часовых уровней. В качестве эталонного сигнала времени используется сигнал глобальных спутниковых систем навигации ГЛОНАСС.
Серверы MSK-IX включены в международный пул NTP-серверов POOL.NTP.ORG.
При необходимости можно запрашивать время на серверах NTP в определённых местах или странах. Например, адрес «de.pool.ntp.org» относится к пулу серверов NTP в Германии (DE). Возможно использовать другие континентальные зоны, такие как Северная Америка, Океания или Азия. Можно добавить числовой префикс и использовать несколько имён серверов, например «0.de.pool.ntp.org», «1.de.pool.ntp.org».
В IDE Arduino есть несколько примеров подключения Esp32 к NTP-серверам для синхронизации системного времени контроллера.

// Advanced.ino
#include <WiFi.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
// Вводим имя и пароль точки доступа
const char* ssid = "OPPO A9 2020";
const char* password = "b277a4ee84e8";
// Инициируем объект NTPClient, указываем российский публичный пул серверов
// точного времени и смещение (в секундах, может быть изменено позже
// с помощью setTimeOffset()). Дополнительно указываем интервал обновления
// (в миллисекундах, может быть изменен с помощью setUpdateInterval()).
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "ntp.msk-ix.ru", 3600, 60000);
void setup()
{
Serial.begin(115200);
// Подключаемся к WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay (500);
Serial.print (".");
}
Serial.println("");
// Переопределяем смещение на 3 часа от "Гринвича"
timeClient.setTimeOffset(3*60*60);
// Запускаем NTPClient
timeClient.begin();
}
// Обновляем и выводим время с интервалом в 1 сек
void loop()
{
timeClient.update();
Serial.print("Время в Петрозаводске: ");
Serial.println(timeClient.getFormattedTime());
delay(1000);
}
Существует два основных протокола для синхронизации времени. NTP (протокол сетевого времени) и SNTP (простой протокол сетевого времени). NTP более точный и сложный, а SNTP — упрощённая версия NTP.
SNTP был специально разработан для небольших компьютеров и микроконтроллеров. Он был спроектирован с учётом более низких требований к памяти и вычислительной мощности, чем NTP. Хотя SNTP гораздо менее точен, чем NTP, он всё равно обеспечивает точность времени в пределах 100 миллисекунд.
Как правило, он используется в небольших сетевых устройствах, таких как IP-камеры, видеорегистраторы, IP-телефоны, маршрутизаторы, потребительские устройства, а также в микроконтроллерах, таких как ESP32.
Для ESP32 основным и является протокол SNTP. Библиотека, которая синхронизирует системное время контроллера по этому протоколу подключается к скетчу следующим образом:
#include "esp_sntp.h"
В следующих примерах показано, как синхронизировать внутренние часы ESP32 со временем, полученным с пула серверов NTP по протоколу SNTP. Это позволяет ESP32 поддерживать точное время, периодически обновляя его с серверов в автоматическом режиме при подключенном WiFi.
Конечно WiFi потребляет ресурсы платы, но после синхронизации времени, он может быть отключен, а для работы с датой и временем будут использоваться свои таймеры контроллера.
Все примеры, опубликованные в статье, были отработаны на программном обеспечении в IDE Arduino для Esp32 от Espressif Systems версии 3.0.6 на контроллере AI-Thinker ESP32-CAM.
В первом примере происходит подключение к пулу серверов, выполняется синхронизация точного времени с внутренними часами контроллера, затем с интервалом в 10 секунд воспроизводится время с внутреннего таймера платы. Кроме этого в фоновом режиме, автоматически, при подключенном WiFi выполняются повторные синхронизации системного времени Esp32 с точным временем по SNTP.
/** Arduino-Esp32-CAM *** SynchronizingESP32clock.ino ***
*
* Синхронизировать дату и время ESP32 с сервером NTP по протоколу SNTP
* (IDE Arduino для Esp32 от Espressif Systems версии 3.0.6
* на контроллере AI-Thinker ESP32-CAM)
*
* v1.1, 11.11.2024 Автор: Труфанов В.Е.
* Copyright © 2024 tve Дата создания: 11.11.2024
**/
#include "WiFi.h"
// Подключаем библиотеку для связи с сервером SNTP, которая является
// библиотекой ядра ESP32 по умолчанию и не требуют установки
#include "esp_sntp.h"
// Вводим имя и пароль точки доступа
const char* ssid = "OPPO A9 2020";
const char* password = "b277a4ee84e8";
// ****************************************************************************
// * Подключить ESP32 к указанной сети Wi-Fi (непрерывно проверять *
// * состояние подключения до тех пор, пока оно не будет успешно установлено *
// ****************************************************************************
void initWiFi()
{
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(100);
}
}
// ****************************************************************************
// * Настроить интервал синхронизации, имя сервера, режим работы и часовой пояс
// ****************************************************************************
void notify(struct timeval* t)
{
Serial.println("Синхронизировано!");
}
void initSNTP()
{
// Определяем, как часто синхронизировать внутренние часы ESP32 с сервером
// SNTP. Интервал указывается в микросекундах. Интервал в 60*60*1000UL
// микросекунд означает синхронизацию каждый час. Разумные интервалы запросов
// обычно составляют от одного-двух раз в день до 5 раз в час.
sntp_set_sync_interval(1 * 60 * 60 * 1000UL);
// Указываем функцию уведомления (callback), которая вызывается при каждой с
// инхронизации. В данном коде для этой цели определяем функцию notify(),
// которая просто выводит «synchronized».
sntp_set_time_sync_notification_cb(notify);
// Устанавливаем режим работы: ESP_SNTP_OPMODE_POLL — просто опрашивать
// сервер SNTP (есть также ESP_SNTP_OPMODE_LISTENONLY)
esp_sntp_setoperatingmode(ESP_SNTP_OPMODE_POLL);
// Указываем имя/адрес сервера. При желании можно указать несколько серверов.
// Например:
// esp_sntp_setservername(0, «pool.ntp.org»);
// esp_sntp_setservername(1, «de.pool.ntp.org»);
// esp_sntp_setservername(2, «time.nist.gov»);
esp_sntp_setservername(0, "pool.ntp.org");
// Запускаем службу SNTP с указанными выше параметрами
esp_sntp_init();
// Устанавливаем часовой пояс, поскольку сервер SNTP
// возвращает время в формате UTC
setTimezone();
}
// ****************************************************************************
// * Настроить часовой пояс *
// ****************************************************************************
void setTimezone()
{
// Здесь устанавливается стандартное время для региона - Европа/Москва
// https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv
setenv("TZ", "MSK-3", 1);
tzset();
}
// ****************************************************************************
// * Ожидать синхронизацию *
// ****************************************************************************
void wait4SNTP()
{
while (sntp_get_sync_status() != SNTP_SYNC_STATUS_COMPLETED)
{
delay(500);
Serial.println("ожидание синхронизации ...");
}
}
// ****************************************************************************
// * Извлечь информацию о текущем времени и вывести ее в отформатированном *
// * виде с помощью struct tm структуры данных: *
// * https://cplusplus.com/reference/ctime/tm/ *
// ****************************************************************************
/*
"%A, %B %d %Y %H:%M:%S" - это спецификаторы формата, которые определяют, как
в struct tm timeinfo; будет отформатирован текст, а члены tm struct следующие:
Тип элемента Значение Диапазон
-----------------------------------------------------
tm_sec int секунды после минуты 0-61*
tm_min int минуты после часа 0-59
tm_hour int часы с полуночи 0-23
tm_mday int день месяца 1-31
tm_mon int месяцы с января 0-11
tm_year int годы с 1900
tm_wday — количество дней с воскресенья 0-6
tm_yday — количество дней с 1 января 0-365
tm_isdst — флаг перехода на летнее время
function strftime() - format time as string:
https://cplusplus.com/reference/ctime/strftime/
*/
void printTime()
{
struct tm timeinfo;
getLocalTime(&timeinfo);
Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}
void setup()
{
Serial.begin(115200);
initWiFi();
initSNTP();
wait4SNTP();
}
void loop()
{
printTime();
delay(10000);
}
// ******************************************** SynchronizingESP32clock.ino ***
В следующем скетче при запуске контроллера проверяется системное время, если время еще не установлено, производится его синхронизация по протоколу SNTP с серверами точного времени, затем контроллер переводится в глубокий сон на несколько секунд, потом просыпается, показывает текущее время и повторяется перевод в глубокий сон.
Кроме этого контроллер использует память таймера RTC для хранения переменной, которая содержит количество перезагрузок ESP32. После каждого “просыпания” значение этого счетчика увеличивается на 1.
Размер памяти RTC в ESP32 составляет 8 кбайт.
/** Arduino-Esp32-CAM *** LwIPSNTPexample.ino ***
*
* Показать синхронизацию системного времени контроллера по протоколу SNTP,
* перевод устройства в "глубокий сон" и вывод из спящего состояния
* с перезапуском и хранением счетчика запусков в памяти таймера RTC
* (IDE Arduino для Esp32 от Espressif Systems версии 3.0.6
* на контроллере AI-Thinker ESP32-CAM)
*
* v1.2, 13.11.2024 Автор: Труфанов В.Е.
* Copyright © 2024 tve Дата создания: 11.11.2024
*
* По материалам статьи: How to synchronize ESP32 clock with SNTP server
* https://www.makerguides.com/how-to-synchronize-esp32-clock-with-sntp-server/
*
* При запуске контроллера проверяется системное время, если время еще не установлено,
* производится его синхронизация по протоколу SNTP с серверами точного времени,
* затем контроллер переводится в глубокий сон на несколько секунд, потом просыпается,
* показывает текущее время и повторяется перевод в глубокий сон.
*
* Кроме этого контроллер использует память RTC для хранения переменной, которая
* содержит количество перезагрузок ESP32. После каждого "просыпания" значение
* этого счетчика увеличивается на 1.
**/
#include <Arduino.h>
#include "nvs_flash.h"
#include "nvs.h"
// Готовим подключение к WiFi через имя и пароль точки доступа
#include "WiFi.h"
const char* ssid = "OPPO A9 2020";
const char* password = "b277a4ee84e8";
// Подключаем библиотеку для связи с сервером SNTP:
// - функция gettimeofday используется для получения текущей метки времени;
// - функция settimeofday используется для установки текущего времени при
// получении ответа от сервера NTP;
// - функция sntp_get_sync_status() используется для получения информации о
// состоянии синхронизации времени. Если время синхронизировано, то возвращается
// ответ SNTP_SYNC_RETURN_COMPLETED. Если состояние сброшено, то возвращается
// SNTP_SYC_STATUS_RESET. Кроме того, если происходит плавная синхронизация
// времени, то возвращается ответ SNTP_SYNC_STATUS_IN_PROGRESS;
// - функция sntp_set_sync_status() используется для установки статуса синхронизации
// времени. Она принимает один параметр — «sync_status», который является
// статусом синхронизации времени;
// - функция sntp_get_sync_mode() используется для получения режима синхронизации
// времени. Эта функция возвращает значение SNTP_SYNC_MODE_IMMEDIATE, если
// синхронизация настроена на немедленное обновление времени. В противном случае
// она возвращает SNTP_SYNC_MODE_SMOOTH - так как настроено плавное обновление времени;
// - функция sntp_set_sync_mode() используется для установки режима синхронизации
// времени. Она принимает один параметр «sync_mode», который является режимом
// синхронизации. Режим может быть SNTP_SYNC_MODE_IMMEDIATE или SNTP_SYNC_MODE_SMOOTH.
// Если выбран режим SNTP_SYNC_MODE_IMMEDIATE, системное время обновляется
// сразу после получения данных с сервера SNTP. Если выбран режим SNTP_SYNC_MODE_SMOOTH,
// устанавливается плавное обновление времени. В этом случае для уведомления
// о времени используется функция adjtime;
// - функция sntp_set_time_sync_notification_cb() используется для установки
// функции обратного вызова по уведомлению о синхронизации времени. Она
// принимает один параметр — функцию обратного вызова.
// ESP32 использует два аппаратных таймера для отслеживания системного
// времени:
// - таймер RTC: позволяет отслеживать время в различных режимах сна, а также
// сохранять время при любых сбросах (за исключением сброса при включении питания,
// который сбрасывает таймер RTC). Отклонение частоты зависит от источников
// тактового сигнала таймера RTC и влияет на точность только в режимах сна,
// в которых время будет измеряться с точностью до 6,6667 мкс;
// - таймер с высоким разрешением: этот таймер недоступен в спящих режимах и не
// сохраняется после перезагрузки, но обладает большей точностью. Таймер
// использует источник тактовых импульсов APB_CLK (обычно 80 МГц), отклонение
// частоты которого составляет менее ±10 частей на миллион. Время измеряется с
// точностью до 1 мкс.
// Системное время можно отслеживать с помощью одного или обоих аппаратных
// таймеров в зависимости от целей приложения и требований к точности системного
// времени (при умалчиваемом режиме подключены оба таймера, это гарантирует, что
// после синхронизации с сервером SNTP время будет отсчитываться с помощью обоих
// таймеров. Когда плата ESP32 будет находиться в режиме глубокого сна, для отслеживания
// времени будет использоваться встроенный таймер RTC, а таймер FRC1 с высоким
// разрешением обеспечит точность времени до микросекунд, пока плата будет
// находиться в активном режиме.
#include "esp_sntp.h"
// Создаем переменную локального времени (секунды с начала эпохи)
time_t now;
// Создаем структуру времени timeinfo в которую будем вкладывать
// выбранное и преобразованное время в секундах с начала эпохи
struct tm timeinfo;
// Объявляем переменную, которая содержит количество перезагрузок ESP32.
// RTC_DATA_ATTR указывает на хранение этой статической переменной типа int
// в памяти RTC. Это гарантирует, что значение boot_count сохранится, когда плата
// ESP32 перейдёт в режим глубокого сна, а затем проснётся.
// Размер памяти RTC в ESP32 составляет 8 кбайт.
RTC_DATA_ATTR static int boot_count = 0;
// ****************************************************************************
// * Подключить ESP32 к указанной сети Wi-Fi (непрерывно проверять *
// * состояние подключения до тех пор, пока оно не будет успешно установлено *
// ****************************************************************************
void initWiFi()
{
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println(" ");
}
// ****************************************************************************
// * Настроить интервал синхронизации, имя сервера, режим работы и часовой пояс
// ****************************************************************************
void notify(struct timeval* t)
{
Serial.println("Синхронизировано!");
}
void initSNTP()
{
// Определяем синхронизирацию внутренних часов ESP32 с сервером
// SNTP через интервал в один час.
sntp_set_sync_interval(1 * 60 * 60 * 1000UL);
// Указываем функцию уведомления (callback) при каждой синхронизации.
sntp_set_time_sync_notification_cb(notify);
// Устанавливаем режим работы: ESP_SNTP_OPMODE_POLL — просто опрашивать
esp_sntp_setoperatingmode(ESP_SNTP_OPMODE_POLL);
// Указываем пул NTP-серверов
esp_sntp_setservername(0, "pool.ntp.org");
// Запускаем службу SNTP с указанными выше параметрами
esp_sntp_init();
// Устанавливаем часовой пояс
setTimezone();
}
// ****************************************************************************
// * Настроить часовой пояс *
// ****************************************************************************
void setTimezone()
{
// Установливаем стандартное время для региона - Европа/Москва
setenv("TZ", "MSK-3", 1);
tzset();
}
// ****************************************************************************
// * Ожидать синхронизацию *
// ****************************************************************************
void wait4SNTP()
{
while (sntp_get_sync_status() != SNTP_SYNC_STATUS_COMPLETED)
{
delay(500);
Serial.println("ожидание синхронизации ...");
}
}
// ****************************************************************************
// * Извлечь информацию о текущем времени и вывести ее в отформатированном *
// * виде с помощью struct tm структуры данных: *
// * https://cplusplus.com/reference/ctime/tm/ *
// ****************************************************************************
/*
"%A, %B %d %Y %H:%M:%S" - это спецификаторы формата, которые определяют, как
в struct tm timeinfo; будет отформатирован текст, а члены tm struct следующие:
Тип элемента Значение Диапазон
-----------------------------------------------------
tm_sec int секунды после минуты 0-61*
tm_min int минуты после часа 0-59
tm_hour int часы с полуночи 0-23
tm_mday int день месяца 1-31
tm_mon int месяцы с января 0-11
tm_year int годы с 1900
tm_wday — количество дней с воскресенья 0-6
tm_yday — количество дней с 1 января 0-365
tm_isdst — флаг перехода на летнее время
function strftime() - format time as string:
https://cplusplus.com/reference/ctime/strftime/
*/
void printTime()
{
struct tm timeinfo;
getLocalTime(&timeinfo);
printf("%d-%d-%d %d:%d:%d\n",
timeinfo.tm_year+1900, timeinfo.tm_mon+1, timeinfo.tm_mday,
timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec);
}
void ViewLocalTime()
{
// Устанавливаем часовой пояс на восточное стандартное время
// и выводим местное время
char strftime_buf[64];
setenv("TZ", "EST5EDT,M3.2.0/2,M11.1.0", 1);
tzset();
localtime_r(&now, &timeinfo);
strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);
printf("Текущие дата и время в Нью-Йорке: %s\n", strftime_buf);
// Устанавливаем часовой пояс на Шанхайское стандартное время
setenv("TZ", "CST-8", 1);
tzset();
localtime_r(&now, &timeinfo);
strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);
printf("Текущие дата и время в Шанхае: %s\n", strftime_buf);
}
void setup()
{
Serial.begin(115200);
initWiFi();
// После каждой перезагрузки увеличиваем счётчик загрузок
// и выводим в терминал.
++boot_count;
printf("Счетчик перезапусков = %d\n", boot_count);
// Выбираем время с начала эпохи
time(&now);
// Переносим время в структуру времени
localtime_r(&now, &timeinfo);
printf("Прошло с 'начала эпохи = 1900 года' %d\n", timeinfo.tm_year);
// Если правильное время ещё не установлено, то настраиваем интервал синхронизации,
// имя сервера, режим работы, часовой пояс и получаем время с сервера SNTP
if (timeinfo.tm_year < (2023 - 1900))
{
ViewLocalTime();
// Показываем начальные заграничное и местное время
setTimezone();
printTime();
Serial.println("Время еще не установлено. Подключаемся к Wi-Fi и получаем время по протоколу SNTP");
// Инициируем SNTP
initSNTP();
wait4SNTP();
// Показываем установленные дату и время
time(&now);
ViewLocalTime();
}
// Показываем местные дату и время
setTimezone();
printTime();
// Переводим систему в глубокий сон на 10 секунд
const int deep_sleep_sec = 10;
printf("Переход в глубокий сон на %d секунд!\n", deep_sleep_sec);
esp_deep_sleep(1000000LL * deep_sleep_sec);
}
void loop()
{
}
// **************************************************** LwIPSNTPexample.ino ***