RTC hoặc Đồng hồ thời gian thực là mô-đun được sử dụng phổ biến nhất trong Điện tử và các thiết bị nhúng để theo dõi thời gian. Nhưng vấn đề với RTC là các vi mạch trong máy tính không chính xác lắm và chúng chỉ có thể cung cấp thời gian của thiết bị cục bộ. Mặt khác, sử dụng internet để lấy thời gian từ máy chủ NTP là giải pháp tốt hơn để lấy thời gian vì nó chính xác hơn và có thể cung cấp thời gian của bất kỳ khu vực địa lý nào trên thế giới. Chúng tôi chỉ cần một mô-đun Wi-Fi và truy cập internet để có thời gian ở bất kỳ vị trí nào trên thế giới bằng cách sử dụng máy chủ NTP. Trong hướng dẫn này, chúng tôi sẽ sử dụng ESP8266 NodeMCU để lấy ngày và giờ hiện tại từ máy chủ NTP và hiển thị nó trên màn hình OLED.
Giao thức thời gian mạng (NTP)
NTP là một trong những Giao thức Internet (IP) mạng lâu đời nhất để đồng bộ hóa đồng hồ giữa các mạng máy tính. Nó được thiết kế bởi David L. Mills của Đại học Delaware vào năm 1981. Giao thức này có thể được sử dụng để đồng bộ hóa nhiều mạng với Giờ phối hợp toàn cầu (UTC) trong vòng vài mili giây. UTC là tiêu chuẩn thời gian chính mà thế giới quy định đồng hồ và thời gian. UTC không thay đổi và thay đổi đối với các vị trí địa lý khác nhau. NTP sử dụng UTC làm tham chiếu thời gian và cung cấp thời gian chính xác và được đồng bộ hóa trên Internet.
NTP hoạt động trên mô hình máy khách-máy chủ phân cấp. Mô hình hàng đầu có các đồng hồ tham chiếu được gọi là "stratum0" như đồng hồ nguyên tử, sóng vô tuyến, GPS, GSM nhận thời gian từ vệ tinh. Các máy chủ nhận thời gian từ stratum0 được gọi là “stratum1” và các máy chủ nhận thời gian từ stratum1 được gọi là “stratum2”, v.v. Điều này tiếp diễn và độ chính xác của thời gian giảm dần sau mỗi giai đoạn. NTP tự động chọn tốt nhất một số nguồn thời gian có sẵn để đồng bộ hóa, giúp nó trở thành giao thức có khả năng chịu lỗi.
Vì vậy, ở đây trong dự án này, chúng tôi lấy thời gian từ máy chủ NTP sử dụng ESP8266 NodeMCU và hiển thị nó trên màn hình OLED. Loại đồng hồ Internet tương tự này được xây dựng bằng cách sử dụng ESP32 trong hướng dẫn trước.
ESP8266 có thể truy cập máy chủ NTP bằng internet để có được thời gian chính xác. Ở đây NTP hoạt động ở chế độ máy khách-máy chủ, ESP8266 hoạt động như thiết bị khách và kết nối với máy chủ NTP bằng UDP (Giao thức dữ liệu người dùng). Máy khách truyền một gói yêu cầu đến các máy chủ NTP và đổi lại NTP sẽ gửi một gói dấu thời gian bao gồm thông tin như độ chính xác, múi giờ, dấu thời gian UNIX, v.v. Sau đó, máy khách tách chi tiết ngày và giờ có thể được sử dụng thêm trong các ứng dụng theo yêu cầu.
Thành phần bắt buộc
- Màn hình OLED 7 chân SSD 1306 0,96 inch đơn sắc
- ESP8266 NodeMCU
- Cáp micro USB
- Breadboard
- Dây nhảy nam sang nam
Sơ đồ mạch và kết nối
Màn hình OLED 7 chân này giao tiếp với module ESP8266 bằng giao thức SPI, dưới đây là sơ đồ mạch và bảng kết nối để kết nối các chân SPI của OLED với NodeMCU để hiển thị thời gian Internet.
Không. |
Màn hình OLED |
NodeMCU |
1 |
GND |
GND |
2 |
VDD |
3,3V |
3 |
SCK |
D5 |
4 |
MOSI (SPI) hoặc SDA (I2C) |
D7 |
5 |
CÀI LẠI |
D3 |
6 |
DC |
D2 |
7 |
CS |
D8 |
Để tìm hiểu thêm về màn hình OLED 7 chân đơn sắc này và giao diện của nó với ESP8266 NodeMCU, hãy theo liên kết.
Giải thích mã
Đầu tiên chúng ta phải tải và cài đặt thư viện NTP vào ESP8266. Có rất nhiều thư viện có sẵn cho NTP Client. Bạn có thể cài đặt bất kỳ chương trình nào trong số chúng từ Arduino IDE. Trong hướng dẫn này, tôi đã cài đặt thư viện NTPClient của Taranais vì nó dễ sử dụng và có các chức năng lấy ngày và giờ từ máy chủ NTP. ESP8266 NodeMCU có thể được lập trình dễ dàng bằng Arduino IDE.
Để cài đặt thư viện NTP, trước tiên hãy tải xuống thư viện bằng liên kết trên, sau đó cài đặt bằng Arduino IDE. Để cài đặt nó, hãy truy cập Sketch> Bao gồm Thư viện> Thêm Thư viện.ZIP , sau đó mở thư mục Zip bằng cách đi đến vị trí bạn đã tải xuống thư mục zip và khởi động lại Arduino IDE.
Thư viện NTPClient đi kèm với các ví dụ. Mở Arduino IDE và Goto Examples> NTPClient> Advanced . Mã được đưa ra trong bản phác thảo này hiển thị thời gian từ máy chủ NTP trên màn hình nối tiếp. Chúng tôi sẽ sử dụng bản phác thảo này để hiển thị ngày và giờ hiện tại trên màn hình OLED.
Mã hoàn chỉnh có ở cuối hướng dẫn này, ở đây tôi đã giải thích một số phần quan trọng của mã.
Thư viện ESP8266WiFi cung cấp các quy trình Wi-Fi cụ thể của ESP8266 để kết nối với mạng. WiFiUDP.h xử lý việc gửi và nhận gói UDP. Vì chúng tôi đang sử dụng giao thức SPI để giao diện OLED với NodeMCU, do đó chúng tôi sẽ nhập thư viện “SPI.h”. Và “Adafruit_GFX.h” và “Adafruit_SSD1306.h” được sử dụng cho Màn hình OLED.
#include
Kích thước OLED của chúng tôi là 128x64, vì vậy chúng tôi đang đặt chiều rộng và chiều cao của màn hình lần lượt là 128 và 64. Vì vậy, xác định các biến cho các chân OLED được kết nối với NodeMCU để giao tiếp SPI.
#define SCREEN_WIDTH 128 // Chiều rộng màn hình OLED, tính bằng pixel #define SCREEN_HEIGHT 64 // Chiều cao màn hình OLED, tính bằng pixel // Khai báo cho màn hình SSD1306 được kết nối bằng phần mềm SPI (trường hợp mặc định): #define OLED_MOSI D7 #define OLED_CLK D5 #define OLED_DC D2 #define OLED_CS D8 #define OLED_RESET D3
Màn hình Adafruit_SSD1306 (SCREEN_WIDTH, SCREEN_HEIGHT, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
Thay thế “your_ssid” và “your_password” bằng SSID Wi-Fi và mật khẩu của bạn trong các dòng mã bên dưới.
const char * ssid = "your_ssid"; const char * password = "your_password";
Thiết lập kết nối WI-Fi bằng cách cấp SSID và mật khẩu cho chức năng WiFi.begin . Kết nối của ESP8266 mất một khoảng thời gian để kết nối với NodeMCU vì vậy chúng tôi phải đợi cho đến khi nó được kết nối.
WiFi.begin (ssid, mật khẩu); while (WiFi.status ()! = WL_CONNECTED) { delay (500); Serial.print ("."); }
Để yêu cầu ngày và giờ, hãy khởi tạo máy khách thời gian với địa chỉ của máy chủ NTP. Để chính xác hơn, hãy chọn địa chỉ của máy chủ NTP gần khu vực địa lý của bạn. Ở đây chúng tôi sử dụng “ pool.ntp.org ” để cung cấp các máy chủ trên toàn thế giới. Nếu bạn muốn chọn máy chủ từ Châu Á, bạn có thể sử dụng “ asia.pool.ntp.org ”. timeClient cũng bù đắp thời gian UTC theo mili giây trong múi giờ của bạn. Ví dụ: chênh lệch UTC cho Ấn Độ là +5: 30, vì vậy chúng tôi chuyển đổi chênh lệch này theo mili giây bằng 5 * 60 * 60 + 30 * 60 = 19800.
Khu vực |
Thời gian bù giờ UTC (giờ và phút) |
Thời gian bù giờ UTC (giây) |
ẤN ĐỘ |
+5: 30 |
19800 |
LONDON |
0:00 |
0 |
NEWYORK |
-5: 00 |
-18000 |
WiFiUDP ntpUDP; NTPClient timeClient (ntpUDP, "pool.ntp.org", 19800,60000);
SSD1306_SWITCHCAPVCC được cấp để tạo ra 3.3V bên trong để khởi tạo màn hình. Khi màn hình OLED khởi động, màn hình hiển thị " CHÀO MỪNG ĐẾN VỚI KỸ THUẬT ĐOẠN MẠCH " với kích thước văn bản 2 và màu XANH LÁ trong 3 giây.
if (! display.begin (SSD1306_SWITCHCAPVCC)) { Serial.println (F ("Phân bổ SSD1306 không thành công")); cho (;;); // Không tiếp tục, lặp mãi mãi } display.clearDisplay (); display.setTextSize (2); // Vẽ văn bản theo tỷ lệ 2X display.setTextColor (BLUE); display.setCursor (5, 2); display.println ("CHÀO MỪNG BẠN ĐẾN"); display.println ("MẠCH"); display.println ("DIGEST"); display.display (); chậm trễ (3000);
Máy khách NTP được khởi tạo bằng cách sử dụng hàm begin () để đặt ngày và giờ từ máy chủ NTP.
timeClient.begin ();
Hàm Update () được sử dụng để nhận ngày và giờ bất cứ khi nào chúng tôi yêu cầu đến máy chủ NTP.
timeClient.update ();
Tốc độ truyền 115200 được đặt để in thời gian trên màn hình nối tiếp.
Serial.begin (115200); Serial.println (timeClient.getFormattedTime ());
getHours (), getMinutes (), getSeconds (), getDay là hàm thư viện và cung cấp giờ, phút, giây và ngày hiện tại từ máy chủ NTP. Mã dưới đây được sử dụng để phân biệt thời gian giữa SA và CH. Nếu giờ chúng ta sử dụng getHours () lớn hơn 12 thì chúng ta đặt thời gian đó là PM khác AM của nó.
int hh = timeClient.getHours (); int mm = timeClient.getMinutes (); int ss = timeClient.getSeconds (); int day = timeClient.getDay (); nếu (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 + "'");
getFormattedDate () được sử dụng để lấy ngày ở định dạng “yyyy-mm-dd” từ máy chủ NTP. Hàm này cung cấp ngày và giờ ở định dạng “yyyy-mm-dd T hh: mm: ss . Nhưng chúng ta chỉ cần ngày tháng vì vậy chúng ta phải chia chuỗi này được lưu trữ ở định dạng date_time cho đến "T" được thực hiện bởi hàm substring () và sau đó lưu trữ ngày trong biến "date" .
date_time = timeClient.getFormattedDate (); int index_date = date_time.indexOf ("T"); Chuỗi ngày = date_time.substring (0, index_date); Serial.println (ngày); display.println (ngày tháng); display.display ();
Đây là cách cuối cùng của Đồng hồ thời gian Internet OLED: