RTC або годинник реального часу - це найбільш часто використовуваний модуль в електроніці та вбудованих пристроях для відстеження часу. Але проблема RTC полягає в тому, що мікросхеми в комп'ютерах не настільки точні, і вони можуть забезпечити лише час роботи локального пристрою. З іншого боку, використання Інтернету для отримання часу з серверів NTP є кращим рішенням для отримання часу, оскільки воно є більш точним і може забезпечити час будь-якої географічної області у світі. Нам просто потрібен модуль Wi-Fi та доступ до Інтернету, щоб отримати час у будь-якому місці у світі за допомогою серверів NTP. У цьому посібнику ми використовуватимемо ESP8266 NodeMCU для отримання поточного часу та дати з серверів NTP та відображення їх на OLED-дисплеї.
Протокол мережевого часу (NTP)
NTP є одним із найстаріших мережевих протоколів Інтернету (IP) для синхронізації годинників між комп'ютерними мережами. Він був розроблений Девідом Л. Міллсом з Університету штату Делавер у 1981 році. Цей протокол може бути використаний для синхронізації багатьох мереж до уніфікованого універсального часу (UTC) протягом декількох мілісекунд. UTC - основний стандарт часу, за яким світ регулює годинник і час. UTC не змінюється і не залежить від різних географічних розташувань. NTP використовує UTC як орієнтир часу і забезпечує точний та синхронізований час в Інтернеті.
NTP працює на ієрархічній моделі клієнт-сервер. Топ-модель має контрольні годинники, відомі як "stratum0", такі як атомні годинники, радіохвилі, GPS, GSM, які отримують час від супутника. Сервери, які отримують час від stratum0, називаються "stratum1", а сервери, які отримують час від stratum1, називаються "stratum2" тощо. Це продовжується, і точність часу зменшується після кожного етапу. NTP автоматично вибирає найкраще з кількох доступних джерел часу для синхронізації, що робить його здатним до відмов протоколом.
Отже, у цьому проекті ми отримуємо час від сервера NTP за допомогою ESP8266 NodeMCU та показуємо його на OLED-дисплеї. Цей самий Інтернет-годинник побудований за допомогою ESP32 у попередньому підручнику.
ESP8266 може отримати доступ до серверів NTP за допомогою Інтернету, щоб отримати точний час. Тут NTP працює в режимі клієнт-сервер, ESP8266 працює як клієнтський пристрій і підключається до серверів NTP за допомогою UDP (User Datagram Protocol). Клієнт передає пакет запитів на сервери NTP, а у відповідь NTP надсилає пакет часової мітки, що складається з такої інформації, як точність, часовий пояс, часова позначка UNIX тощо. Потім клієнт відокремлює деталі дати та часу, які можуть бути використані в додатках відповідно до вимог.
Потрібні компоненти
- Монохромний 7-контактний OLED-дисплей SSD1306 0,96 ”
- ESP8266 NodeMCU
- Кабель Micro USB
- Макет
- Провід перемички від чоловіка до чоловіка
Схема та з'єднання
Цей 7-контактний OLED-дисплей взаємодіє з модулем ESP8266, використовуючи протокол SPI, нижче наведені принципова схема та таблиця з'єднань для з'єднання OLED-контактів SPI з NodeMCU для відображення часу в Інтернеті.
Ні. |
OLED-дисплей |
NodeMCU |
1 |
GND |
GND |
2 |
VDD |
3,3 В |
3 |
SCK |
D5 |
4 |
MOSI (SPI) або SDA (I2C) |
D7 |
5 |
СКИНУТИ |
D3 |
6 |
Постійного струму |
D2 |
7 |
CS |
D8 |
Щоб дізнатись більше про цей монохромний 7-контактний OLED-дисплей та його взаємодію з ESP8266 NodeMCU, перейдіть за посиланням.
Пояснення коду
Спочатку нам потрібно завантажити та встановити бібліотеку NTP у ESP8266. Для клієнта NTP доступно багато бібліотек. Ви можете встановити будь-який з них із Arduino IDE. У цьому посібнику я встановив бібліотеку NTPClient від Taranais, оскільки вона проста у використанні та має функції отримання дати та часу з серверів NTP. ESP8266 NodeMCU можна легко запрограмувати за допомогою Arduino IDE.
Щоб встановити бібліотеку NTP, спочатку завантажте бібліотеку за посиланням вище, а потім встановіть її за допомогою Arduino IDE. Щоб встановити його, перейдіть до Sketch> Include Library> Add.ZIP Library , а потім відкрийте папку Zip, перейшовши до місця, де ви завантажили папку zip, і перезапустіть IDE Arduino.
Бібліотека NTPClient постачається із прикладами. Відкрийте Arduino IDE і перейдіть до Прикладів> NTPClient> Додатково . Код, наведений у цьому ескізі, відображає час від сервера NTP на послідовному моніторі. Ми використаємо цей ескіз для відображення поточного часу та дати на OLED-дисплеї.
Повний код доступний в кінці цього підручника, тут я пояснив декілька важливих частин коду.
Бібліотека ESP8266WiFi забезпечує специфічні для ESP8266 підпрограми Wi-Fi для підключення до мережі. WiFiUDP.h обробляє надсилання та отримання пакетів UDP. Оскільки ми використовуємо протокол SPI для інтерфейсу OLED з NodeMCU, тому ми імпортуємо бібліотеку “SPI.h”. А для OLED-дисплея використовуються "Adafruit_GFX.h" та "Adafruit_SSD1306.h".
#включати
Наш розмір OLED становить 128x64, тому ми встановлюємо ширину та висоту екрана як 128 та 64 відповідно. Тож визначте змінні для OLED-контактів, підключених до NodeMCU для зв'язку SPI.
#define SCREEN_WIDTH 128 // OLED ширина дисплея, у пікселях #define SCREEN_HEIGHT 64 // OLED display display, in pixels // Декларація для SSD1306 дисплея, підключеного за допомогою програмного забезпечення SPI (типовий випадок): #define OLED_MOSI D7 #define OLED_CLK D5 #define OLED_DC D2 #define OLED_CS D8 #define OLED_RESET D3
Дисплей Adafruit_SSD1306 (SCREEN_WIDTH, SCREEN_HEIGHT, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
Замініть “your_ssid” та “your_password” на ваш SSID Wi-Fi та пароль у нижченаведених рядках коду.
const char * ssid = "your_ssid"; const char * password = "ваш_пароль";
Налаштуйте з'єднання WI-Fi, надавши SSID і пароль функції WiFi.begin . Підключення ESP8266 займає деякий час, щоб підключитися до NodeMCU, тому нам доведеться почекати, поки він підключиться.
WiFi.begin (ssid, пароль); while (WiFi.status ()! = WL_CONNECTED) { затримка (500); Serial.print ("."); }
Щоб запитати дату та час, ініціалізуйте клієнта часу адресою серверів NTP. Для кращої точності виберіть адресу серверів NTP, які знаходяться поблизу вашого географічного регіону. Тут ми використовуємо “ pool.ntp.org ”, який надає сервери з усього світу. Якщо ви хочете обрати сервери з Азії, ви можете використовувати “ asia.pool.ntp.org ”. timeClient також приймає зміщення часу UTC у мілісекундах вашого часового поясу. Наприклад, зміщення UTC для Індії становить +5: 30, тому ми перетворюємо цей зсув у мілісекундах, що дорівнює 5 * 60 * 60 + 30 * 60 = 19800.
Площа |
Зміщення часу за UTC (години та хвилини) |
Зсув часу UTC (секунди) |
ІНДІЯ |
+5: 30 |
19800 |
ЛОНДОН |
0:00 |
0 |
НЬЮ-ЙОРК |
-5: 00 |
-18000 |
WiFiUDP ntpUDP; NTPClient timeClient (ntpUDP, "pool.ntp.org", 19800,60000);
SSD1306_SWITCHCAPVCC призначений для внутрішньої генерації 3.3V для ініціалізації дисплея. Коли OLED запускається, на дисплеї відображається “ WELCOME TO CIRCUIT DIGEST ” із розміром тексту 2 та кольором СИНИЙ протягом 3 секунд.
якщо (! display.begin (SSD1306_SWITCHCAPVCC)) { Serial.println (F ("Помилка розподілу SSD1306")); для (;;); // Не продовжуйте, цикл назавжди } display.clearDisplay (); display.setTextSize (2); // Намалюйте текстовий дисплей у масштабі 2X.setTextColor (СИНИЙ); display.setCursor (5, 2); display.println ("ДОБРО ВІТАЄМО В"); display.println ("СХЕМА"); display.println ("DIGEST"); display.display (); затримка (3000);
Клієнт NTP ініціалізується за допомогою функції begin () для встановлення дати та часу з серверів NTP.
timeClient.begin ();
Функція Update () використовується для отримання дати та часу, коли ми запитуємо до серверів NTP.
timeClient.update ();
Швидкість передачі даних 115200 встановлена для друку часу на послідовному моніторі.
Serial.begin (115200); Serial.println (timeClient.getFormattedTime ());
getHours (), getMinutes (), getSeconds (), getDay - це функція бібліотеки, яка надає поточну годину, хвилини, секунди та день з сервера NTP. Наведений нижче код використовується для розмежування часу між AM та PM. Якщо година, яку ми отримуємо за допомогою getHours () , перевищує 12, тоді ми встановлюємо цей час як PM, а інший час - AM.
int hh = timeClient.getHours (); int mm = timeClient.getMinutes (); int ss = timeClient.getSeconds (); int day = timeClient.getDay (); якщо (hh> 12) { hh = hh-12; display.print (hh); display.print (":"); display.print (мм); display.print (":"); display.print (ss); display.println ("PM"); } ще { display.print (чч); display.print (":"); display.print (мм); display.print (":"); display.print (ss); display.println ("AM"); } int day = timeClient.getDay (); display.println ("'" + arr_days + "'");
getFormattedDate () використовується дата отримання у форматі “рррр-мм-дд” із сервера NTP. Ця функція задає дату та час у форматі “рррр-мм-дд Т год: мм: сс . Але нам потрібна лише дата, тому нам доведеться розділити цей рядок, який зберігається у форматі date_time , до “T”, що виконується функцією substring (), а потім зберегти дату у змінній “date” .
date_time = timeClient.getFormattedDate (); int index_date = date_time.indexOf ("T"); Рядок date = date_time.substring (0, index_date); Serial.println (дата); display.println (дата); display.display ();
Ось як нарешті виглядатиме годинник OLED в Інтернеті: