Часы реального времени (RTC) – это наиболее часто используемый модуль в электронике и встраиваемых устройствах для отслеживания времени. Но проблема с RTC заключается в том, что микросхемы в компьютерах не настолько точны, и они могут обеспечить только время локального устройства. С другой стороны, использование Интернета с целью получения времени с NTP-серверов является лучшим решением для получения точного времени, поскольку оно более точное и может предоставить время для любой географической области в мире. Нам просто нужен модуль Wi-Fi и доступ к Интернету, чтобы узнать время в любой точке мира с помощью NTP-серверов.

В этом проекте мы будем использовать ESP8266 NodeMCU, чтобы получать текущее время и дату с серверов NTP и отображать их на OLED-дисплее.
NTP является одним из старейших сетевых интернет-протоколов (IP) для синхронизации часов между компьютерными сетями. Он был разработан Дэвидом Л. Миллсом (David L. Mills) из Университета штата Делавэр в 1981 году. Этот протокол можно использовать для синхронизации многих сетей с всемирным координированным временем (UTC) в течение нескольких миллисекунд. UTC является основным стандартом времени, по которому мир настраивает часы и время. База UTC остается постоянной, лишь значение времени в часах адаптируется для разных географических мест. NTP использует UTC в качестве эталона времени и обеспечивает точное и синхронизированное время через Интернет.
NTP работает по иерархической модели клиент-сервер. Верхняя модель имеет эталонные часы, известные как «stratum0», такие как атомные часы, радиоволны, GPS, GSM, которые получают время со спутника. Серверы, которые получают время от stratum0, называются «stratum1», а серверы, которые получают время от stratum1, называются «stratum2» и так далее. Это продолжается, и точность времени продолжает уменьшаться после каждого этапа. NTP автоматически выбирает лучший из нескольких доступных источников времени для синхронизации, что делает его отказоустойчивым протоколом.
Итак, в этом примере, мы будем получать время с NTP-сервера с помощью ESP8266 NodeMCU и отображать его на OLED-дисплее.

ESP8266 может получить доступ к NTP-серверам через Интернет, чтобы получить точное время. Здесь NTP работает в режиме клиент-сервер, ESP8266 работает как клиентское устройство и соединяется с NTP-серверами по протоколу UDP (User Datagram Protocol). Клиент передает пакет запроса на NTP-серверы и, в свою очередь, NTP отправляет пакет метки времени, который содержит такую информацию, как точность, часовой пояс, метка времени UNIX и т.д. Затем клиент разделяет элементы даты и времени, которые могут в дальнейшем использоваться в приложениях в соответствии с требованиями.
Схема подключения проекта довольно проста. Из аппаратного обеспечения помимо ESP8266 используется OLED-дисплей. Этот 7-выводной OLED-дисплей принимает данные от модуля ESP8266 по протоколу SPI. Ниже приведена принципиальная схема для подключения контактов OLED SPI к плате ESP8266 NodeMCU для отображения времени Интернета.

Теперь перейдем к программированию ESP8266. Сначала мы должны загрузить и установить библиотеку NTP для ESP8266. Для клиента NTP доступно множество библиотек. Вы можете установить любую из них из Arduino IDE. В этом руководстве мы установим библиотеку NTPClient от Taranais (https://github.com/arduino-libraries/NTPClient/archive/master.zip), потому что она проста в использовании и имеет функции для получения даты и времени с серверов NTP. ESP8266 NodeMCU может быть легко запрограммирован с помощью Arduino IDE.

Чтобы установить библиотеку NTP, сначала загрузите эту библиотеку, используя приведенную выше ссылку, а затем установите ее с помощью Arduino IDE. Чтобы установить ее, перейдите в Скетч – Включить библиотеку – Добавить библиотеку .ZIP (Sketch – Include Library – Add .ZIP Library), затем распакуйте папку Zip и перезапустите Arduino IDE.

Библиотека NTPClient поставляется с примерами. Откройте Arduino IDE и перейдите к примерам (Examples – NTPClient – Advanced). Код, приведенный в этом скетче, отображает время от NTP-сервера на последовательном мониторе. Мы будем использовать этот скетч для отображения текущего времени и даты на OLED-дисплее.

Полный код приведен далее, а сейчас просто кратко рассмотрим функции библиотеки. getHours(), getMinutes(), getSeconds(), getDay являются библиотечными функциями и выдают текущий час, минуты, секунды и день с NTP-сервера.
Функция getFormattedDate() используется для получения даты в формате «гггг-мм-дд» с NTP-сервера. Эта функция выдает дату и время в формате «гггг-мм-дд T чч:мм:сс». Но нам нужна только дата, поэтому мы должны разделить эту строку, которая хранится в формате date_time, до «T», что делается функцией substring(), а затем сохранить дату в переменной «date».
#include <NTPClient.h>
#include <ESP8266WiFi.h> // предоставляет специальные процедуры Wi-Fi для ESP8266, которые мы вызываем для подключения к сети
#include <WiFiUdp.h> // обрабатывает отправку и получение пакетов UDP
#include <SPI.h> // SPI для сопряжения OLED с NodeMCU
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // Ширина OLED-дисплея, в пикселях
#define SCREEN_HEIGHT 64 // Высота OLED-дисплея в пикселях
// Объявления для дисплея SSD1306, подключенного с использованием программного SPI (по умолчанию):
#define OLED_MOSI D7
#define OLED_CLK D5
#define OLED_DC D2
#define OLED_CS D8
#define OLED_RESET D3
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT,OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
const char *ssid = "CircuitLoop";
const char *password = "circuitdigest101";
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", 19800,60000);
String arr_days[]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
String date_time;
// Вы можете указать пул сервера времени и смещение (в секундах, может быть изменено позже с помощью setTimeOffset ())
// Кроме того, вы можете указать интервал обновления (в миллисекундах, можно изменить с помощью setUpdateInterval ())
void setup(){
Serial.begin(115200);
WiFi.begin(ssid, password);
while ( WiFi.status() != WL_CONNECTED ) {
delay ( 500 );
Serial.print ( "." );
}
if(!display.begin(SSD1306_SWITCHCAPVCC))
{
Serial.println(F("SSD1306 allocation failed"));
for(;;); // бесконечный цикл
}
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(5, 2);
display.println("WELCOME TO");
display.println(" CIRCUIT");
display.println(" DIGEST");
display.display();
delay(3000);
timeClient.begin();
}
void loop() {
timeClient.update();
display.clearDisplay();
Serial.println(timeClient.getFormattedTime());
display.setTextSize(2);
display.setTextColor(BLUE);
display.setCursor(0, 2);
int hh = timeClient.getHours();
int mm = timeClient.getMinutes();
int ss = timeClient.getSeconds();
if(hh>12)
{
hh=hh-12;
display.print(hh);
display.print(":");
display.print(mm);
display.print(":");
display.print(ss);
display.println(" PM");
}
else
{
display.print(hh);
display.print(":");
display.print(mm);
display.print(":");
display.print(ss);
display.println(" AM");
}
int day = timeClient.getDay();
display.println("'"+arr_days[day]+"'");
date_time = timeClient.getFormattedDate();
int index_date = date_time.indexOf("T");
String date = date_time.substring(0, index_date);
Serial.println(date);
display.println(date);
display.display();
}
В результате работа интернет-часов на основе ESP8266 может выглядеть следующим образом:

© digitrode.ru