МикроконтроллерESP32, благодаря встроенным возможностям Wi-Fi, является популярной платформой для проектов Интернета вещей (IoT). Во многих таких приложениях, особенно связанных с регистрацией данных (data logging) или планированием задач, требуется точная синхронизация времени. Получение актуальной даты и времени необходимо для присвоения временных меток событиям или измерениям. Одним из наиболее распространенных и эффективных методов синхронизации времени для устройств, подключенных к сети, является использование протокола сетевого времени (NTP - Network Time Protocol).
Данный урок демонстрирует процесс настройки ESP32 в качестве NTP-клиента для запроса точного времени с публичных NTP-серверов с использованием среды разработки Arduino IDE. Преимущество этого подхода заключается в отсутствии необходимости использования дополнительных аппаратных модулей, таких как часы реального времени (RTC), при условии наличия у ESP32 активного интернет-соединения.
Перед выполнением инструкций, изложенных в данном руководстве, убедитесь, что в вашей среде Arduino IDE установлено дополнение для поддержки плат ESP32. Инструкции по установке можно найти в официальной документации или соответствующих руководствах:
NTP (Network Time Protocol) — это сетевой протокол, предназначенный для синхронизации внутренних часов компьютерных систем через сети с переменной латентностью. Иными словами, он используется для согласования времени между различными устройствами в сети, обеспечивая высокую точность.
Существуют общедоступные NTP-серверы, такие как pool.ntp.org
, которые предоставляют услуги синхронизации времени любому устройству (клиенту). В рассматриваемом сценарии ESP32 выступает в роли NTP-клиента, который отправляет запрос на сервер pool.ntp.org
для получения текущего времени.
Диаграмма взаимодействия:
[ESP32 (NTP Client)] -------- NTP Request --------> [pool.ntp.org (NTP Server)]
[ESP32 (NTP Client)] <------- NTP Response -------- [pool.ntp.org (NTP Server)]
(Содержит точное время)
Для получения даты и времени с использованием ESP32 и Arduino IDE не требуется установка сторонних библиотек для работы с NTP. Необходимые функции входят в состав стандартной библиотеки time.h
, которая является частью ESP32 core для Arduino. Вам потребуется только библиотека WiFi.h
для установления сетевого соединения.
Следующий программный код демонстрирует получение даты и времени с NTP-сервера и вывод результатов в Монитор последовательного порта Arduino IDE. Код основан на примере, поставляемом с библиотекой time.h
.
Исходный код
/* * Клиент-сервер NTP на ESP32: Получение даты и времени. * https://arduino-tex.ru/news/211/klient-server-ntp-na-esp32-poluchenie-daty-i-vremeni.html */ #include <WiFi.h> // Библиотека для работы с Wi-Fi #include "time.h" // Стандартная библиотека C для работы со временем // --- Параметры сети Wi-Fi --- const char* ssid = "YOUR_SSID"; // Замените на имя вашей Wi-Fi сети const char* password = "YOUR_PASSWORD"; // Замените на пароль вашей Wi-Fi сети // --- Параметры NTP --- const char* ntpServer = "pool.ntp.org"; // Адрес публичного NTP сервера // Смещение относительно времени по Гринвичу (GMT) в секундах. // Пример: для GMT+3 установите 3 * 3600. Для Москвы (UTC+3) значение 10800. const long gmtOffset_sec = 10800; // Смещение для перехода на летнее время в секундах. // Обычно 1 час (3600 секунд) или 0, если летнее время не используется. const int daylightOffset_sec = 0; // Прототип функции для вывода времени void printLocalTime(); // --- Функция начальной настройки --- void setup() { Serial.begin(115200); // Инициализация последовательного порта для вывода отладочной информации // Подключение к сети Wi-Fi Serial.print("Подключение к Wi-Fi сети: "); Serial.println(ssid); WiFi.begin(ssid, password); // Начать процесс подключения while (WiFi.status() != WL_CONNECTED) { // Ожидание успешного подключения delay(500); Serial.print("."); } Serial.println(""); Serial.println("Wi-Fi подключено."); Serial.print("IP адрес: "); Serial.println(WiFi.localIP()); // Вывод полученного IP-адреса // Инициализация и получение времени с NTP сервера // configTime(смещение_GMT_сек, смещение_летнего_времени_сек, адрес_NTP_сервера) configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); // Первоначальный вывод времени после синхронизации printLocalTime(); // Отключение Wi-Fi после получения времени (опционально, для экономии энергии) // Если время требуется обновлять периодически, Wi-Fi отключать не следует. // WiFi.disconnect(true); // WiFi.mode(WIFI_OFF); // Serial.println("Wi-Fi отключен."); } // --- Основной цикл программы --- void loop() { // Задержка в 1 секунду (1000 миллисекунд) delay(1000); // Вывод текущего локального времени каждую секунду printLocalTime(); } // --- Функция для получения и вывода локального времени --- void printLocalTime() { struct tm timeinfo; // Структура для хранения компонентов времени // Попытка получить локальное время. // getLocalTime() возвращает false, если время еще не синхронизировано. if (!getLocalTime(&timeinfo)) { Serial.println("Не удалось получить время с NTP сервера."); return; // Выход из функции, если время не получено } // Вывод времени в стандартном формате: День недели, Месяц День Год Час:Минута:Секунда // Функция strftime форматирует время из структуры tm в строку согласно спецификаторам формата. char timeStringBuff[50]; // Буфер для отформатированной строки времени strftime(timeStringBuff, sizeof(timeStringBuff), "%A, %B %d %Y %H:%M:%S", &timeinfo); Serial.println(timeStringBuff); // Вывод полной строки времени // --- (Опционально) Детальный вывод компонентов времени --- Serial.print("День недели: "); strftime(timeStringBuff, sizeof(timeStringBuff), "%A", &timeinfo); // %A - полное название дня недели Serial.println(timeStringBuff); Serial.print("Месяц: "); strftime(timeStringBuff, sizeof(timeStringBuff), "%B", &timeinfo); // %B - полное название месяца Serial.println(timeStringBuff); Serial.print("День месяца: "); strftime(timeStringBuff, sizeof(timeStringBuff), "%d", &timeinfo); // %d - день месяца (01-31) Serial.println(timeStringBuff); Serial.print("Год: "); strftime(timeStringBuff, sizeof(timeStringBuff), "%Y", &timeinfo); // %Y - год (4 цифры) Serial.println(timeStringBuff); Serial.print("Час (24ч): "); strftime(timeStringBuff, sizeof(timeStringBuff), "%H", &timeinfo); // %H - час (00-23) Serial.println(timeStringBuff); Serial.print("Час (12ч): "); strftime(timeStringBuff, sizeof(timeStringBuff), "%I", &timeinfo); // %I - час (01-12) Serial.println(timeStringBuff); Serial.print("Минута: "); strftime(timeStringBuff, sizeof(timeStringBuff), "%M", &timeinfo); // %M - минута (00-59) Serial.println(timeStringBuff); Serial.print("Секунда: "); strftime(timeStringBuff, sizeof(timeStringBuff), "%S", &timeinfo); // %S - секунда (00-59) Serial.println(timeStringBuff); // --- (Опционально) Пример сохранения компонентов времени в переменные --- Serial.println("Переменные времени:"); char timeHour[3]; // Буфер для часов (2 цифры + нуль-терминатор) strftime(timeHour, sizeof(timeHour), "%H", &timeinfo); Serial.print("Час сохраненный в переменную: "); Serial.println(timeHour); char timeWeekDay[10]; // Буфер для дня недели (макс. ~9 символов + нуль-терминатор) strftime(timeWeekDay, sizeof(timeWeekDay), "%A", &timeinfo); Serial.print("День недели сохраненный в переменную: "); Serial.println(timeWeekDay); Serial.println(); // Пустая строка для разделения выводов }
Рассмотрим ключевые части приведенного кода:
#include <WiFi.h> // Для управления Wi-Fi соединением #include "time.h" // Стандартная библиотека C для работы со временемБиблиотека
WiFi.h
необходима для подключения ESP32 к сети Интернет. Библиотека time.h
предоставляет функции для работы со временем, включая получение времени от NTP-сервера (configTime
, getLocalTime
) и его форматирование (strftime
).const char* ssid = "YOUR_SSID"; const char* password = "YOUR_PASSWORD";В этих константных строках необходимо указать имя (SSID) и пароль вашей Wi-Fi сети. Эти данные используются функцией
WiFi.begin()
для установления соединения.ntpServer
):
const char* ntpServer = "pool.ntp.org";Указывает адрес пула NTP-серверов.
pool.ntp.org
— это распределенная сеть серверов времени, обеспечивающая надежность и доступность. Можно использовать и другие региональные пулы (например, ru.pool.ntp.org
) или конкретные адреса NTP-серверов.gmtOffset_sec
):
const long gmtOffset_sec = 10800;Определяет разницу в секундах между вашим часовым поясом и временем по Гринвичу (GMT/UTC). Важно: Установите это значение в соответствии с вашим часовым поясом. Например, для Москвы (UTC+3) значение будет
3 * 3600 = 10800
. Для Центральноевропейского времени (CET, UTC+1) значение будет 1 * 3600 = 3600
. Информацию о смещениях часовых поясов можно найти в интернете.daylightOffset_sec
):
const int daylightOffset_sec = 0;Определяет смещение в секундах для учета перехода на летнее время. Обычно это значение равно
3600
(1 час) или 0
, если в вашем регионе летнее время не используется или вы не хотите его учитывать. Система автоматически применяет это смещение в соответствующие периоды (если базовое ядро ESP32 содержит актуальные правила перехода).setup()
:
Serial.begin(115200)
настраивает последовательный порт для вывода сообщений.WiFi.begin(ssid, password)
, устанавливает соединение с указанной Wi-Fi сетью. Цикл while (WiFi.status() != WL_CONNECTED)
ожидает завершения подключения.configTime(gmtOffset_sec, daylightOffset_sec, ntpServer)
инициализирует внутреннюю систему времени ESP32, указывая ей использовать NTP-сервер и заданные смещения для расчета локального времени.printLocalTime()
осуществляется для немедленного вывода времени после успешной инициализации.WiFi.disconnect(true);
и WiFi.mode(WIFI_OFF);
могут быть использованы для отключения Wi-Fi модуля после получения времени, что полезно для снижения энергопотребления в проектах с батарейным питанием, где постоянное подключение не требуется.loop()
:
В основном цикле программы с помощью delay(1000)
создается пауза в 1 секунду, после чего вызывается функция printLocalTime()
для регулярного обновления и вывода текущего времени в Монитор последовательного порта.printLocalTime()
:
struct tm timeinfo;
. Структура tm
определена в time.h
и используется для хранения компонентов даты и времени (секунды, минуты, часы, день, месяц, год и т.д.).
tm
(согласно документации C):
tm_sec
: Секунды после минуты (0-59)tm_min
: Минуты после часа (0-59)tm_hour
: Часы с полуночи (0-23)tm_mday
: День месяца (1-31)tm_mon
: Месяцы с января (0-11)tm_year
: Годы с 1900tm_wday
: Дни с воскресенья (0-6)tm_yday
: Дни с 1 января (0-365)tm_isdst
: Флаг летнего времени (положительное значение, если активно, 0 если нет, отрицательное - если информация недоступна)getLocalTime(&timeinfo)
пытается заполнить структуру timeinfo
текущим локальным временем, рассчитанным на основе последней синхронизации с NTP и заданных смещений. Она возвращает true
в случае успеха и false
, если время еще не было успешно синхронизировано (например, сразу после запуска или при отсутствии сети).strftime(buffer, bufferSize, format, &timeinfo)
используется для форматирования даты и времени из структуры timeinfo
в строку (buffer
) в соответствии с заданным форматом (format
).%A
: Полное название дня недели (на английском, например, "Monday")%B
: Полное название месяца (на английском, например, "January")%d
: День месяца как число с ведущим нулем (01-31)%Y
: Год в 4-значном формате (например, 2023)%H
: Час в 24-часовом формате (00-23)%I
: Час в 12-часовом формате (01-12)%M
: Минута как число с ведущим нулем (00-59)%S
: Секунда как число с ведущим нулем (00-59)%a
- сокращенный день недели, %b
- сокращенный месяц, %y
- год (2 цифры), и т.д. См. документацию по strftime
).%H
) в символьные массивы (строки) с помощью strftime
. Это может быть полезно для дальнейшей обработки или использования в логике программы. Обратите внимание на размер буфера, который должен быть достаточным для хранения строки и терминатора (\0
).YOUR_SSID
и YOUR_PASSWORD
на реальные данные вашей Wi-Fi сети.gmtOffset_sec
и daylightOffset_sec
в соответствии с вашим географическим положением и правилами перехода на летнее время.Пример вывода в Мониторе последовательного порта.
Заключение.
В данном руководстве был рассмотрен метод получения точной даты и времени на микроконтроллере ESP32 с использованием протокола NTP и среды разработки Arduino IDE. Были продемонстрированы настройка Wi-Fi соединения, конфигурация параметров NTP (адрес сервера, смещение GMT, учет летнего времени) и использование стандартных функций библиотеки time.h
для получения и форматирования времени.
Этот подход является эффективным решением для проектов, требующих временных меток или синхронизации по времени, при условии наличия доступа к сети Интернет. Он устраняет необходимость в дополнительных аппаратных часах реального времени (RTC), упрощая схему и снижая стоимость устройства.
Важно помнить, что данный метод полностью зависит от наличия активного интернет-соединения для первоначальной синхронизации и периодических обновлений. Если ваш проект требует надежного отсчета времени даже при отсутствии сети, необходимо использовать альтернативные решения, такие как внешние модули RTC (например, DS1307, DS3231), которые имеют собственный источник питания (батарейку) и продолжают отсчет времени автономно.
Дополнительная информация к данному уроку:
Понравился урок: Клиент-сервер NTP на ESP32: Получение даты и времени (Arduino IDE)? Не забудь поделиться с друзьями в соц. сетях.
А также подписаться на наш канал на YouTube, вступить в группу Вконтакте, в Telegram.
Спасибо за внимание!
Технологии начинаются с простого!
Фотографии к статье
Файлы для скачивания
![]() |
Код из урока.ino | 7 Kb | 31 | Скачать |
Уроки ESP32 (заметки)
31 марта , 2025
Комментариев:0
Файлов для скачивания:1
Фото:2
Понравилась статья? Нажми
Виджеты для Easy HMI
Читайте также
Мы в соц сетях
Комментарии