Получение времени и даты с NTP сервера c помощью ESP8266
В этом руководстве вы узнаете, как получить дату и время с NTP-сервера, используя ESP8266  с Arduino IDE. Рассмотрим пример программы и библиотеку NTPclient.
Получение времени и даты с NTP сервера c помощью ESP8266
03.05.2024 в 07:40   3681 0
Версия для печати

Получение времени и даты с NTP сервера

лого

В этом руководстве вы узнаете, как получить дату и время с NTP-сервера, используя ESP8266 NodeMCU с Arduino IDE. Получение даты и времени полезно в проектах регистрации данных для определения показаний временных меток. Чтобы получать время с NTP-сервера, ESP8266 должен иметь подключение к Интернету, и вам не нужно дополнительное оборудование (например, часы RTC).

NTP (протокол сетевого времени)

NTP расшифровывается как протокол сетевого времени и представляет собой сетевой протокол для синхронизации часов между компьютерными системами. Другими словами, он используется для синхронизации времени работы компьютера в сети.

Существуют NTP-серверы, такие как pool.ntp.org который любой желающий может использовать для запроса времени в качестве клиента. В этом случае ESP8266 является NTP-клиентом, который запрашивает время у NTP-сервера (pool.ntp.org ).

обмен данными

Установка библиотеки NtpClient

Для получения времени мы будем использовать библиотеку NtpClient. В вашей Arduino IDE перейдите в SketchБиблиотекаУправление библиотеками. Должен открыться менеджер библиотеки.

Найдите NtpClient и установите библиотеку Фабриса Вайнбера, как показано на следующем рисунке.

выбор библиотеки

Функции времени библиотеки NtpClient

Библиотека NtpClient поставляется со следующими функциями для возврата времени:

getDay() – возвращает число int, соответствующее дню недели (от 0 до 6), начинающемуся в воскресенье;

getHours() – возвращает число int с текущим часом (от 0 до 23) в 24-часовом формате;

getMinutes() – возвращает номер int с текущими минутами (от 0 до 59);

getSeconds() – возвращает номер int с текущей секундой;

getEpochTime() – возвращает неподписанный long с указанием времени эпохи (количество секунд, прошедших с 1 января 1970 года (полночь по Гринвичу);

getFormattedTime() – возвращает строку со временем в формате HH: MM:SS;

В этой библиотеке нет функций для возврата даты, но мы покажем вам в коде, как получить дату (день, месяц и год).

Код ESP8266 NodeMCU

Следующий код соединяет ESP8266 с NTP-сервером (pool.ntp.org ) запросить дату и время. Он отображает текущую дату и время в нескольких форматах на последовательном мониторе.
 

#include <ESP8266WiFi.h>
#include <NTPClient.h>
#include <WiFiUdp.h>

// Replace with your network credentials
const char *ssid = "REPLACE_WITH_YOUR_SSID";
const char *password = "REPLACE_WITH_YOUR_PASSWORD";

// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org");

//Week Days
String weekDays[7]={"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

//Month names
String months[12]={"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};

void setup() {
 // Initialize Serial Monitor
 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(".");
 }

// Initialize a NTPClient to get time
 timeClient.begin();
 // Set offset time in seconds to adjust for your timezone, for example:
 // GMT +1 = 3600
 // GMT +3 = 10800
 // GMT +8 = 28800
 // GMT -1 = -3600
 // GMT 0 = 0
 timeClient.setTimeOffset(10800);
}

void loop() {
 timeClient.update();

 time_t epochTime = timeClient.getEpochTime();
 Serial.print("Epoch Time: ");
 Serial.println(epochTime);
 
 String formattedTime = timeClient.getFormattedTime();
 Serial.print("Formatted Time: ");
 Serial.println(formattedTime); 

 int currentHour = timeClient.getHours();
 Serial.print("Hour: ");
 Serial.println(currentHour); 

 int currentMinute = timeClient.getMinutes();
 Serial.print("Minutes: ");
 Serial.println(currentMinute); 
 
 int currentSecond = timeClient.getSeconds();
 Serial.print("Seconds: ");
 Serial.println(currentSecond); 

 String weekDay = weekDays[timeClient.getDay()];
 Serial.print("Week Day: ");
 Serial.println(weekDay); 

 //Get a time structure
 struct tm *ptm = gmtime ((time_t *)&epochTime); 

 int monthDay = ptm->tm_mday;
 Serial.print("Month day: ");
 Serial.println(monthDay);

 int currentMonth = ptm->tm_mon+1;
 Serial.print("Month: ");
 Serial.println(currentMonth);

 String currentMonthName = months[currentMonth-1];
 Serial.print("Month name: ");
 Serial.println(currentMonthName);

 int currentYear = ptm->tm_year+1900;
 Serial.print("Year: ");
 Serial.println(currentYear);

 //Print complete date:
 String currentDate = String(currentYear) + "-" + String(currentMonth) + "-" + String(monthDay);
 Serial.print("Current date: ");
 Serial.println(currentDate);

 Serial.println("");

 delay(2000);
}

Как работает код

Во-первых, включите необходимые библиотеки.

#include <ESP8266WiFi.h>
#include <NTPClient.h>
#include <WiFiUdp.h>

Введите свои сетевые учетные данные в следующие переменные, чтобы ESP8266 мог подключиться к вашему маршрутизатору, чтобы иметь доступ к Интернету для запроса даты и времени с NTP-сервера.

const char *ssid = "REPLACE_WITH_YOUR_SSID";
const char *password = "REPLACE_WITH_YOUR_PASSWORD";

Определите NTP-клиент для получения даты и времени.

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org");

Мы запросим время у pool.ntp.org , который представляет собой кластер временных серверов, которые любой желающий может использовать для запроса времени. Затем мы создаем два массива для хранения названий дней недели и месяцев.

//Week Days
String weekDays[7]={"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

//Month names
String months[12]={"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};

Блок Setup ()

В setup () инициализируйте последовательный монитор для отображения информации.

 
Serial.begin(115200);

Затем подключите ESP8266 к Интернету.

// Connect to Wi-Fi
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
 delay(500);
 Serial.print(".");
}

Инициализируйте NtpClient.

timeClient.begin();

Установка часового пояса

Вы можете использовать метод setTimeOffset(), чтобы настроить время для вашего часового пояса в секундах.
timeClient.setTimeOffset(3600);

Вот несколько примеров для разных часовых поясов:

  • GMT +1 = 3600
  • GMT +3 = 10800
  • GMT +8 = 28800
  • GMT -1 = -3600
  • GMT 0 = 0
Мы живем в России, поэтому для GMT+3 пишем.
timeClient.setTimeOffset(10800);

Основной цикл loop()

В loop() вызовите функцию update(), чтобы получить текущую дату и время с NTP-сервера.

 
timeClient.update();

Получение времени

Затем мы можем использовать функции, предоставляемые библиотекой, для получения времени. Например, чтобы получить время эпохи:

 
unsigned long epochTime = timeClient.getEpochTime();
Serial.print("Epoch Time: ");
Serial.println(epochTime);

Функция getFormattedTime() возвращает время в формате HH:MM:SS.

String formattedTime = timeClient.getFormattedTime();
Serial.print("Formatted Time: ");
Serial.println(formattedTime); 

Вы можете получить часы, минуты или секунды отдельно, используя функции ,getHours(), getMinutes() и getSeconds() следующим образом:

int currentHour = timeClient.getHours();
Serial.print("Hour: ");
Serial.println(currentHour); 

int currentMinute = timeClient.getMinutes();
Serial.print("Minutes: ");
Serial.println(currentMinute); 
 
int currentSecond = timeClient.getSeconds();
Serial.print("Seconds: ");
Serial.println(currentSecond); 

Получение даты

Функция getDay() возвращает число от 0 до 6, в котором 0 соответствует воскресенью, а 6 - субботе. Итак, мы можем получить доступ к названию дня недели из массива, который мы создали ранее, следующим образом

String weekDay = weekDays[timeClient.getDay()];
Serial.print("Week Day: ");
Serial.println(weekDay); 

Клиент NTP не поставляется с функциями для получения даты. Итак, нам нужно создать временную структуру (struct tm), а затем получить доступ к ее элементам, чтобы получить информацию о дате.

struct tm *ptm = gmtime ((time_t *)&epochTime);

Временная структура содержит следующие элементы:

  • tm_sec: секунды после минуты;
  • tm_min: минуты после часа;
  • tm_hour: часы с полуночи;
  • tm_mday: день месяца;
  • tm_year: годы с 1900 года;
  • tm_wday: дни с воскресенья;
  • tm_yday: дни с 1 января;
  • tm_isdst: флаг перехода на летнее время;

В следующих строках указывается день месяца следующим образом:

int monthDay = ptm->tm_mday;
Serial.print("Month day: ");
Serial.println(monthDay);

Чтобы получить другие элементы, вы используете аналогичный подход. Например, за месяц:

int currentMonth = ptm->tm_mon+1;
Serial.print("Month: ");
Serial.println(currentMonth);

Поскольку tm_mday начинается с 0, мы добавляем 1 к месяцу, чтобы январь соответствовал 1, февраль - 2 и так далее.

Затем мы можем получить название месяца, используя массив месяцев, который мы создали ранее. Нумерация массивов начинается с 0, поэтому мы вычитаем 1.

 

String currentMonthName = months[currentMonth-1];
Serial.print("Month name: ");
Serial.println(currentMonthName);

Чтобы получить год, нам нужно добавить 1900, потому что tm_year сохраняет количество лет после 1900.

int currentYear = ptm->tm_year+1900;
Serial.print("Year: ");
Serial.println(currentYear);

Наконец, мы создаем строку с именем currentDate, которая содержит текущую дату в формате ГГГГ-ММ-ДД.

String currentDate = String(currentYear) + "-" + String(currentMonth) + "-" + String(monthDay);
 Serial.print("Current date: ");
 Serial.println(currentDate);

Демонстрация работы

После ввода ваших сетевых учетных данных и изменения переменных, чтобы настроить время в соответствии с вашим часовым поясом, протестируйте пример.

Загрузите код на свою плату ESP8266. Убедитесь, что выбраны правильная плата и COM-порт.

Откройте последовательный монитор со скоростью передачи 115200 бод. Дата и время должны отображаться в нескольких форматах, как показано ниже.

пример работы

Подведение итогов

В этом уроке вы узнали, как получить дату и время с NTP-сервера с помощью ESP8266. Это особенно полезно для проектов регистрации данных, имеющих доступ к Интернету.



Источник: https://randomnerdtutorials.com/esp8266-nodemcu-date-time-ntp-client-server-arduino/
Материал также доступен на моем канале: Яндекс Дзен и в группе ВК
Категория: Программирование | Добавил: :, (29.12.2022)
Просмотров: 3681 | Теги: ESP8266, NTPclient, синхронизация времени, Arduino IDE | Рейтинг: 0.0/0
Поделиться:
Всего комментариев: 0
avatar