ESP32 NTP клиент-сервер: получение даты и времени (Arduino IDE)

Узнайте, как запрашивать дату и время с NTP-сервера с помощью ESP32 в Arduino IDE. Получение даты и времени полезно в проектах регистрации данных для отметки времени показаний. Для получения времени от NTP-сервера ESP32 должен иметь подключение к Интернету, и вам не нужно дополнительное оборудование (например, часы реального времени RTC).

ESP32 NTP клиент-сервер получение даты и времени Arduino IDE

Перед тем как приступить к этому руководству, вам необходимо установить дополнение 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 запрос времени и даты

Получение даты и времени от 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: флаг летнего времени;

  • Документация структуры tm.

Получите все данные о дате и времени и сохраните их в структуре 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, и вы должны получать дату и время каждую секунду, как показано на следующем рисунке.

ESP32 получение даты и времени NTP клиент-сервер Arduino IDE вывод Serial Monitor

Заключение

В этом руководстве вы узнали, как получить дату и время от NTP-сервера с помощью ESP32, запрограммированного в Arduino IDE. Теперь вы можете использовать полученные знания для отметки времени показаний датчиков в своих проектах.

Этот метод работает только если ESP32 подключен к Интернету. Если ваш проект не имеет доступа к интернету, вам нужно использовать другой метод. Вы можете использовать модуль RTC, например DS1307.

Если вы хотите узнать больше об ESP32, ознакомьтесь с нашими ресурсами:


Источник: ESP32 NTP Client-Server: Get Date and Time (Arduino IDE)