Рубрики
Проекты на ESP8266

Интернет часы на NodeMCU ESP8266 и OLED дисплее с определением времени по протоколу NTP

Модули часов реального времени (Real Time Clock, RTC) находят широкое применение в современной электронике для определения текущего времени и даты. Но недостатком данных модулей является то, что они не всегда обеспечивают требуемую точность определения даты и времени. При этом они могут определять только время на локальном устройстве. В данном случае использование решений, основанных на получении точного времени с серверов NTP, обеспечивает большую точность измерения времени и позволяет производить определение точного времени в любой точке земного шара.

Для реализации этой идеи можно использовать Wi-Fi модуль, который будет подключаться к сети интернет и определять время в любой точке Земли с помощью серверов NTP. В данной статье мы рассмотрим использование платы NodeMCU ESP8266 (будет выполнять роль Wi-Fi модуля) для считывания текущего времени и даты с серверов NTP и их отображения на экране OLED дисплея.

Также на нашем сайте вы можете посмотреть все проекты с использованием систем реального времени.

Необходимые компоненты

  1. NodeMCU ESP8266 (купить на AliExpress).
  2. SSD1306 0.96” OLED дисплей с 7 контактами (купить на AliExpress).
  3. Кабель micro USB.
  4. Макетная плата.
  5. Соединительные провода «папа-папа».

Протокол NTP

Протокол сетевого времени (Network Time Protocol, NTP) – это самый старый протокол, который появился в IP сетях для синхронизации времени между компьютерными сетями. Он был разработан ученым David L. Mills в университете Delaware в 1981 году. Данный протокол может быть использован для синхронизации времени различных сетей к всеобщему скоординированному времени (Coordinated Universal Time, UTC) с точностью до нескольких миллисекунд. UTC – это основной стандарт времени в современном мире, который регулирует время и дату. Протокол NTP использует UTC в качестве системного времени и обеспечивает точное синхронизированное время во всей сети Интернет.

Протокол NTP работает на основе иерархической модели клиент-сервер. На самом верхнем уровне этой модели используются системные часы известные как “stratum0”, в качестве которых могут использоваться атомные часы, радиоволны, GPS, GSM, которые получают сигналы времени от спутника. Серверы, которые получают сигналы времени от stratum0, называются “stratum1”, а серверы, которые получают сигналы времени от stratum1, называются “stratum2” и т.д. Это приводит к тому, что точность времени уменьшается при переходе вниз по уровням модели. При этом протокол NTP автоматически выбирает самый лучший из доступных серверов времени для синхронизации, что обеспечивает хорошую отказоустойчивость данного протокола.

В данном проекте мы будем получать точное время от сервера NTP с помощью платы NodeMCU ESP8266 и показывать его на экране OLED дисплея. Также на нашем сайте вы можете прочитать статью о подключении OLED дисплея к NodeMCU ESP8266.

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

Схема проекта

Схема интернет часов на NodeMCU ESP8266 и OLED дисплее представлена на следующем рисунке.

OLED дисплей в нашем проекте подключается к NodeMCU ESP8266 по протоколу SPI. Полная схема соединений между NodeMCU ESP8266 и OLED дисплеем представлена в следующей таблице.

OLED дисплей NodeMCU ESP8266
GND GND
VDD 3.3V
SCK D5
MOSI (SPI) или SDA (I2C) D7
RESET D3
DC D2
CS D8

Более подробно о подключении OLED дисплея к NodeMCU ESP8266 можно прочитать в этой статье.

Объяснение программы для модуля ESP8266

Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.

Сначала в программе нам необходимо скачать и установить библиотеку NTP для модуля ESP8266 – таких библиотек достаточно много, вы можете использовать любую из них. Мы в данном проекте использовали библиотеку NTPClient от разработчика Taranais (скачать ее можно по этой ссылке) – она достаточно проста в использовании и содержит функции для получения времени и даты с серверов NTP. Плату ESP8266 NodeMCU мы будем программировать с помощью Arduino IDE.

Для установки библиотеки NTPClient скачайте ее по вышеприведенной ссылке, затем в Arduino IDE откройте пункт меню to Sketch > Include Library > Add .ZIP Library и укажите путь к папке, куда вы скачали Zip архив библиотеки. После этого перезагрузите Arduino IDE.

Библиотека NTPClient содержит примеры, открыть которые можно в пункте меню Examples > NTPClient > Advanced. Код в скетче данного примера позволяет считывать время с NTP сервера и отображать его в окне монитора последовательной связи. Мы возьмем код этого скетча за основу программы для нашего проекта и будем отображать текущее время и дату на OLED дисплее.

Библиотека ESP8266WiFi содержит Wi-Fi функции, позволяющие модулю ESP8266 подключаться к сети интернет. WiFiUDP.h содержит функции для передачи и приема UDP пакетов. Поскольку OLED дисплей мы подключаем к нашей плате NodeMCU ESP8266 по интерфейсу SPI, то нам необходимо в программе подключить библиотеку “SPI.h”. Библиотеки “Adafruit_GFX.h” и “Adafruit_SSD1306.h” будут использоваться для взаимодействия с OLED дисплеем.

Также в программе нам необходимо задать ширину и высоту экрана OLED дисплея – это 128 и 64 пикселов соответственно. Также зададим контакты, к которым подключен OLED дисплей по интерфейсу SPI.

В следующем фрагменте кода вам необходимо заменить значения параметров “your_ssid” и “your_password” на идентификатор сети (SSID) и пароль для своей сети Wi-Fi.

Далее с помощью наших SSID и пароля установим соединение с сетью Wi-Fi с помощью функции WiFi.begin. Подключение к сети Wi-Fi отнимает некоторое время, поэтому подождите.

Для запроса времени и даты инициализируйте клиент времени с адресом NTP сервера. Для лучшей точности результатов выберите адрес NTP сервера, самого ближнего к вашей географической области. В нашем случае мы использовали пул “pool.ntp.org”, который обеспечивает доступ к серверам по всему земному шару. Если вы хотите использовать серверы из Азии, вы можете использовать сервер “asia.pool.ntp.org”. Клиент времени (timeClient) также использует временной сдвиг UTC в миллисекундах для вашей временной зоны. К примеру, временной сдвиг UTC для Индии составляет +5:30, поэтому его конвертацию в миллисекунды выполним следующим образом: 5*60*60+30*60 = 19800.

Зона UTC time offset(hours and minutes) UTC time offset (миллисекунды)
Индия +5:30 19800
Лондон 0:00 0
Нью-Йорк -5:00 -18000

При инициализации OLED дисплея мы будем использовать параметр SSD1306_SWITCHCAPVCC чтобы напряжение 3.3V для дисплея получать от его внутреннего источника. При инициализации дисплея мы на его экран будем выводить приветственное сообщение “WELCOME TO CIRCUIT DIGEST” на 3 секунд с размером текста равным 2 и синим цветом текста.

Далее мы будем инициализировать NTP клиент с помощью функции timeClient.begin() чтобы в дальнейшем получать время и дату с сервера NTP.

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

Инициализируем последовательную связь со скоростью 115200 чтобы выводить принимаемые значения времени в окно монитора последовательной связи (serial monitor).

Далее мы будем использовать функции getHours(), getMinutes(), getSeconds(), getDay чтобы получить текущие значения часов, минут, секунд и дней с NTP сервера. Также мы будем производить разделение времени на AM и PM (по полудня и после полудня). Если число часов, определяемое с помощью функции getHours(), будет больше 12, мы установим время как PM, иначе как AM.

Функция getFormattedDate() используется для получения даты в формате “yyyy-mm-dd” с NTP сервера. Эта функция считывает дату и время в формате “yyyy-mm-dd T hh:mm:ss. Но нам нужна только дата, поэтому нам из этой строковой переменной нужно вырезать кусок строки, который расположен слева от символа “T” – эту операцию мы будем осуществлять с помощью функции substring() и затем сохранять полученное значение даты в переменной “date”.

На следующем рисунке показан внешний вид работы наших интернет часов на основе платы NodeMCU ESP8266 и OLED дисплея.

Исходный код программы (скетча)

Источник статьи

8 ответов к “Интернет часы на NodeMCU ESP8266 и OLED дисплее с определением времени по протоколу NTP”

Здравствуйте, спасибо за статью! Решил переделать свои часы на ардуино и DS1302, которые безбожно спешили. ESP8266, конечно, огорчает малым количеством «безопасных» пинов. Не понимаю людей, которым не понравилась статья. Как по мне — это отличная база для собственных проектов

Добрый день. Ну люди бывают разные, всем не угодишь. А вам спасибо за «добрый» комментарий

Ни где не могу найти проект с часами синхронизирующимися по спутнику. Может кто ссылку кинет ?

Еще одна поделка индийского школьника, не имеющая практической ценности. Зачем такое публиковать?..
Посудите сами: жестко зашитые в код WiFi user name-password жестко зашитый в код часовой пояс, отсутствие перехода на декретное время, индийский формат времени “am-pm”. И зачем-то быстрый и дорогой SPI дисплей (а такой был!) вместо недорогого I2C.
Понятно, что все это допиливается. А если человек просто хочет САМ сделать часы и не быть при этом программистом?
Сделает. Включит, покрутит, разочаруется, плюнет, выбросит и пойдет купит дешевые китайские, в Фикспрайсе.

user name-password в коде несложно же изменить. А как вы все это по другому хотели видеть? Чтобы они с клавиатуры вводились? SPI дисплей вроде бы рублей на 50 всего дороже чем I2C дисплей, на мой взгляд не такая существенная разница, видимо в момент создания этого проекта именно он был у них под руками, а на I2C дисплее у них тоже проектов много. И статьи на том индийском сайте публикуют не школьники, а вполне себе взрослые и грамотные люди — я с их сайта перевел много статей и в связи с этим много про них знаю.

Если правильно понял, если Интернет временно не доступен, не работает timeClient.update нет времени, нет часов?

Ну, так и есть. Как говорится, без интернета жизни в современном мире нет )) Если у вас периоды отсутствия интернета происходят достаточно часто, то вы можете дополнить этот проект модулем часов реального времени и когда нет интернета считывать значение времени с этого модуля

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *