ESP32 NTP клиент-сервер: получение даты и времени (Arduino IDE)
Узнайте, как запрашивать дату и время с NTP-сервера с помощью ESP32 в Arduino IDE. Получение даты и времени полезно в проектах регистрации данных для отметки времени показаний. Для получения времени от NTP-сервера ESP32 должен иметь подключение к Интернету, и вам не нужно дополнительное оборудование (например, часы реального времени RTC).
Перед тем как приступить к этому руководству, вам необходимо установить дополнение ESP32 в Arduino IDE:
Рекомендуется: Получение даты и времени с ESP8266 NodeMCU NTP клиент-сервер
NTP (Network Time Protocol)
NTP расшифровывается как Network Time Protocol (протокол сетевого времени) – это сетевой протокол для синхронизации часов между компьютерными системами. Другими словами, он используется для синхронизации времени компьютерных часов в сети.
Существуют NTP-серверы, такие как pool.ntp.org, которые любой может использовать для запроса времени в качестве клиента. В этом случае ESP32 является NTP-клиентом, который запрашивает время у NTP-сервера (pool.ntp.org).
Получение даты и времени от NTP-сервера
Для получения даты и времени с ESP32 вам не нужно устанавливать никаких библиотек. Вам просто нужно подключить библиотеку time.h в свой код.
Следующий код получает дату и время от NTP-сервера и выводит результаты в Serial Monitor. Он основан на примере, предоставленном библиотекой time.h.
/*
Rui Santos
Complete project details at https://RandomNerdTutorials.com/esp32-date-time-ntp-client-server-arduino/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
*/
#include <WiFi.h>
#include "time.h"
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 0;
const int daylightOffset_sec = 3600;
void setup(){
Serial.begin(115200);
// Connect to Wi-Fi
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected.");
// Init and get the time
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
printLocalTime();
//disconnect WiFi as it's no longer needed
WiFi.disconnect(true);
WiFi.mode(WIFI_OFF);
}
void loop(){
delay(1000);
printLocalTime();
}
void printLocalTime(){
struct tm timeinfo;
if(!getLocalTime(&timeinfo)){
Serial.println("Failed to obtain time");
return;
}
Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
Serial.print("Day of week: ");
Serial.println(&timeinfo, "%A");
Serial.print("Month: ");
Serial.println(&timeinfo, "%B");
Serial.print("Day of Month: ");
Serial.println(&timeinfo, "%d");
Serial.print("Year: ");
Serial.println(&timeinfo, "%Y");
Serial.print("Hour: ");
Serial.println(&timeinfo, "%H");
Serial.print("Hour (12 hour format): ");
Serial.println(&timeinfo, "%I");
Serial.print("Minute: ");
Serial.println(&timeinfo, "%M");
Serial.print("Second: ");
Serial.println(&timeinfo, "%S");
Serial.println("Time variables");
char timeHour[3];
strftime(timeHour,3, "%H", &timeinfo);
Serial.println(timeHour);
char timeWeekDay[10];
strftime(timeWeekDay,10, "%A", &timeinfo);
Serial.println(timeWeekDay);
Serial.println();
}
Как работает код
Давайте быстро рассмотрим код, чтобы понять, как он работает. Сначала подключите библиотеки для соединения с Wi-Fi и получения времени.
#include <WiFi.h>
#include "time.h"
Настройка SSID и пароля
Введите учетные данные вашей сети в следующие переменные, чтобы ESP32 мог установить интернет-соединение и получить дату и время от NTP-сервера.
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
NTP-сервер и настройки времени
Затем вам нужно определить следующие переменные для настройки и получения времени от NTP-сервера: ntpServer, gmtOffset_sec и daylightOffset_sec.
NTP-сервер
Мы будем запрашивать время у pool.ntp.org, который представляет собой кластер серверов времени, который любой может использовать для запроса времени.
const char* ntpServer = "pool.ntp.org";
Смещение GMT
Переменная gmtOffset_sec определяет смещение в секундах между вашим часовым поясом и GMT. Мы живем в Португалии, поэтому смещение времени равно 0. Измените переменную gmtOffset_sec в соответствии с вашим часовым поясом.
const long gmtOffset_sec = 0;
Смещение летнего времени
Переменная daylightOffset_sec определяет смещение в секундах для перехода на летнее время. Обычно это один час, что соответствует 3600 секундам.
const int daylightOffset_sec = 3600;
setup()
В setup() вы инициализируете последовательную связь на скорости 115200 бод для вывода результатов:
Serial.begin(115200);
Следующие строки подключают ESP32 к вашему маршрутизатору.
// Connect to Wi-Fi
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected.");
Настройте время с помощью параметров, определенных ранее:
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
printLocalTime()
После настройки времени вызовите функцию printLocalTime() для вывода времени в Serial Monitor.
В этой функции создайте структуру времени (struct tm) под названием timeinfo, которая содержит все детали о времени (минуты, секунды, часы и т.д.).
struct tm timeinfo;
Структура tm содержит календарную дату и время, разбитые на компоненты:
tm_sec: секунды после минуты;
tm_min: минуты после часа;
tm_hour: часы с полуночи;
tm_mday: день месяца;
tm_year: годы с 1900;
tm_wday: дни с воскресенья;
tm_yday: дни с 1 января;
tm_isdst: флаг летнего времени;
Получите все данные о дате и времени и сохраните их в структуре timeinfo.
if(!getLocalTime(&timeinfo)){
Serial.println("Failed to obtain time");
return;
}
Затем выведите все данные о времени в Serial Monitor.
Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
Serial.print("Day of week: ");
Serial.println(&timeinfo, "%A");
Serial.print("Month: ");
Serial.println(&timeinfo, "%B");
Serial.print("Day of Month: ");
Serial.println(&timeinfo, "%d");
Serial.print("Year: ");
Serial.println(&timeinfo, "%Y");
Serial.print("Hour: ");
Serial.println(&timeinfo, "%H");
Serial.print("Hour (12 hour format): ");
Serial.println(&timeinfo, "%I");
Serial.print("Minute: ");
Serial.println(&timeinfo, "%M");
Serial.print("Second: ");
Serial.println(&timeinfo, "%S");
Для доступа к элементам структуры даты и времени вы можете использовать следующие спецификаторы:
Спецификатор |
Описание |
|---|---|
%A |
Полное название дня недели |
%B |
Полное название месяца |
%d |
День месяца |
%Y |
Год |
%H |
Час в 24-часовом формате |
%I |
Час в 12-часовом формате |
%M |
Минута |
%S |
Секунда |
Существуют и другие спецификаторы, которые можно использовать для получения информации в другом формате, например: сокращенное название месяца (%b), сокращенное название дня недели (%a), номер недели с первым воскресеньем как первым днем первой недели (%U) и другие (подробнее).
Мы также покажем вам пример, если вы хотите сохранить информацию о времени в переменных. Например, если вы хотите сохранить час в переменную с именем timeHour, создайте переменную типа char длиной 3 символа (она должна вместить символы часа плюс завершающий символ). Затем скопируйте информацию о часе из структуры timeinfo в переменную timeHour с помощью функции strftime().
Serial.println("Time variables");
char timeHour[3];
strftime(timeHour,3, "%H", &timeinfo);
Serial.println(timeHour);
Для получения других переменных используйте аналогичный процесс. Например, для дня недели нам нужно создать переменную типа char длиной 10 символов, потому что самый длинный день недели содержит 9 символов (saturday).
char timeWeekDay[10];
strftime(timeWeekDay,10, "%A", &timeinfo);
Serial.println(timeWeekDay);
Serial.println();
Демонстрация
После ввода учетных данных вашей сети и изменения переменных для настройки часового пояса и летнего времени вы можете протестировать пример.
Загрузите код на плату ESP32. Убедитесь, что выбрана правильная плата и COM-порт. После загрузки кода нажмите кнопку «Enable» на ESP32, и вы должны получать дату и время каждую секунду, как показано на следующем рисунке.
Заключение
В этом руководстве вы узнали, как получить дату и время от NTP-сервера с помощью ESP32, запрограммированного в Arduino IDE. Теперь вы можете использовать полученные знания для отметки времени показаний датчиков в своих проектах.
Этот метод работает только если ESP32 подключен к Интернету. Если ваш проект не имеет доступа к интернету, вам нужно использовать другой метод. Вы можете использовать модуль RTC, например DS1307.
Если вы хотите узнать больше об ESP32, ознакомьтесь с нашими ресурсами:
Источник: ESP32 NTP Client-Server: Get Date and Time (Arduino IDE)