RTC หรือ Real Time Clock เป็นโมดูลที่ใช้กันมากที่สุดในอุปกรณ์อิเล็กทรอนิกส์และอุปกรณ์ฝังตัวเพื่อติดตามเวลา แต่ปัญหาของ RTC คือไมโครชิปในคอมพิวเตอร์นั้นไม่ค่อยแม่นยำเท่าไหร่นักและสามารถระบุเวลาของอุปกรณ์ภายในเครื่องได้เท่านั้น ในทางกลับกันการใช้อินเทอร์เน็ตเพื่อดึงเวลาจากเซิร์ฟเวอร์ NTP เป็นทางออกที่ดีกว่าสำหรับการหาเวลาเนื่องจากมีความแม่นยำมากขึ้นและสามารถระบุเวลาของพื้นที่ทางภูมิศาสตร์ใด ๆ ในโลกได้ เราต้องการโมดูล Wi-Fi และเข้าถึงอินเทอร์เน็ตเพื่อหาเวลาจากสถานที่ใด ๆ ในโลกโดยใช้เซิร์ฟเวอร์ NTP ในการกวดวิชานี้เราจะใช้ ESP8266 NodeMCU ที่จะได้รับวันและเวลาปัจจุบันจากเซิร์ฟเวอร์ NTP และแสดงบนจอแสดงผล
โปรโตคอลเวลาเครือข่าย (NTP)
NTP เป็นหนึ่งใน Internet Protocol (IP) เครือข่ายที่เก่าแก่ที่สุดสำหรับการซิงโครไนซ์นาฬิการะหว่างเครือข่ายคอมพิวเตอร์ ได้รับการออกแบบโดย David L. Mills จาก University of Delaware ในปี 1981 โปรโตคอลนี้สามารถใช้เพื่อซิงโครไนซ์เครือข่ายจำนวนมากกับCoordinated Universal Time (UTC)ภายในไม่กี่มิลลิวินาที UTC เป็นมาตรฐานเวลาหลักที่โลกควบคุมนาฬิกาและเวลา UTC ไม่เปลี่ยนแปลงและแตกต่างกันไปตามสถานที่ตั้งทางภูมิศาสตร์ที่แตกต่างกัน NTP ใช้ UTC เป็นตัวอ้างอิงเวลาและให้เวลาที่ถูกต้องและตรงกันทางอินเทอร์เน็ต
NTP ทำงานบนรูปแบบไคลเอนต์เซิร์ฟเวอร์แบบลำดับชั้น รุ่นยอดนิยมมีนาฬิกาอ้างอิงที่เรียกว่า“ stratum0”เช่นนาฬิกาอะตอมคลื่นวิทยุ GPS GSM ซึ่งรับเวลาจากดาวเทียม เซิร์ฟเวอร์ที่รับเวลาจาก stratum0 เรียกว่า"stratum1"และเซิร์ฟเวอร์ที่รับเวลาจาก stratum1 เรียกว่า"stratum2"เป็นต้น สิ่งนี้จะดำเนินต่อไปและความแม่นยำของเวลาจะลดลงหลังจากแต่ละขั้นตอน NTP จะเลือกแหล่งเวลาที่ดีที่สุดโดยอัตโนมัติเพื่อซิงโครไนซ์ซึ่งทำให้โปรโตคอลสามารถทนต่อความผิดพลาดได้
ดังนั้นที่นี่ในโครงการนี้เราจะได้รับเวลาจากเซิร์ฟเวอร์ NTP ใช้ ESP8266 NodeMCU และการแสดงบนจอแสดงผล นาฬิกาอินเทอร์เน็ตประเภทเดียวกันนี้สร้างขึ้นโดยใช้ ESP32 ในบทช่วยสอนก่อนหน้านี้
ESP8266 สามารถเข้าถึงเซิร์ฟเวอร์ NTP โดยใช้อินเทอร์เน็ตเพื่อรับเวลาที่แม่นยำ ที่นี่ NTP ทำงานในโหมดไคลเอนต์เซิร์ฟเวอร์ESP8266 ทำงานเป็นอุปกรณ์ไคลเอนต์และเชื่อมต่อกับเซิร์ฟเวอร์ NTPโดยใช้ UDP (User Datagram Protocol) ไคลเอนต์ส่งแพ็กเก็ตคำร้องขอไปยังเซิร์ฟเวอร์ NTP และในทางกลับกัน NTP จะส่งแพ็กเก็ตการประทับเวลาซึ่งประกอบด้วยข้อมูลเช่นความถูกต้องเขตเวลาการประทับเวลา UNIX เป็นต้นจากนั้นไคลเอนต์จะแยกรายละเอียดวันที่และเวลาซึ่งสามารถใช้เพิ่มเติมในแอปพลิเคชันตามความต้องการ
ส่วนประกอบที่จำเป็น
- จอภาพ Monochrome 7-pin SSD1306 0.96” OLED
- ESP8266 NodeMCU
- สายไมโคร USB
- เขียงหั่นขนม
- สายจัมเปอร์ชายถึงชาย
แผนภาพวงจรและการเชื่อมต่อ
นี้ 7 พิน OLED สื่อสารการแสดงผลที่มี ESP8266 โมดูลโดยใช้โปรโตคอล SPI ด้านล่างมีแผนภาพวงจรและการเชื่อมต่อตารางการเชื่อมต่อขา SPI OLED กับ NodeMCU เวลาอินเทอร์เน็ตการแสดงผล
ไม่ |
จอแสดงผล OLED |
NodeMCU |
1 |
GND |
GND |
2 |
VDD |
3.3V |
3 |
SCK |
D5 |
4 |
MOSI (SPI) หรือ SDA (I2C) |
D7 |
5 |
รีเซ็ต |
D3 |
6 |
กระแสตรง |
D2 |
7 |
CS |
D8 |
หากต้องการเรียนรู้เพิ่มเติมจอแสดงผล OLED แบบ Monochrome 7 พินและการเชื่อมต่อกับ ESP8266 NodeMCU โปรดไปที่ลิงค์
คำอธิบายรหัส
ก่อนอื่นเราต้องดาวน์โหลดและติดตั้งไลบรารี NTP ใน ESP8266 มีไลบรารีมากมายสำหรับไคลเอนต์ NTP คุณสามารถติดตั้งได้จาก Arduino IDE ในบทช่วยสอนนี้ฉันได้ติดตั้งไลบรารี NTPClient โดย Taranais เนื่องจากใช้งานง่ายและมีฟังก์ชันในการรับวันที่และเวลาจากเซิร์ฟเวอร์ NTP ESP8266 NodeMCU สามารถตั้งโปรแกรมได้อย่างง่ายดายโดยใช้ Arduino IDE
ในการติดตั้งไลบรารี NTP ขั้นแรกให้ดาวน์โหลดไลบรารีโดยใช้ลิงก์ด้านบนจากนั้นติดตั้งโดยใช้ Arduino IDE หากต้องการติดตั้งให้ไปที่ Sketch> รวมไลบรารี> เพิ่ม. ZIP Library จากนั้นเปิดโฟลเดอร์ Zip โดยไปที่ตำแหน่งที่คุณดาวน์โหลดโฟลเดอร์ zip และรีสตาร์ท Arduino IDE
ห้องสมุด NTPClient มาพร้อมกับตัวอย่าง เปิด Arduino IDE และ ไปตัวอย่าง> NtpClient> ขั้นสูง รหัสที่ระบุในแบบร่างนี้แสดงเวลาจากเซิร์ฟเวอร์ NTP บนมอนิเตอร์แบบอนุกรม เราจะใช้ภาพร่างนี้เพื่อแสดงเวลาและวันที่ปัจจุบันบนจอแสดงผล OLED
โค้ดที่สมบูรณ์มีอยู่ในตอนท้ายของบทช่วยสอนนี้ฉันได้อธิบายส่วนสำคัญบางส่วนของโค้ดที่นี่
ไลบรารี ESP8266WiFiมีรูทีน Wi-Fi เฉพาะของ ESP8266 เพื่อเชื่อมต่อกับเครือข่าย WiFiUDP.hจัดการการส่งและรับแพ็คเกจ UDP เนื่องจากเราใช้โปรโตคอล SPI เพื่อเชื่อมต่อ OLED กับ NodeMCU ดังนั้นเราจึงนำเข้าไลบรารี“ SPI.h” และ“ Adafruit_GFX.h” และ“ Adafruit_SSD1306.h” ใช้สำหรับจอแสดงผล OLED
# รวม
ขนาด OLED ของเราคือ 128x64 ดังนั้นเราจึงตั้งค่าความกว้างและความสูงของหน้าจอเป็น 128 และ 64 ตามลำดับ ดังนั้นกำหนดตัวแปรสำหรับหมุด OLED ที่เชื่อมต่อกับ NodeMCU สำหรับการสื่อสาร SPI
# กำหนด SCREEN_WIDTH 128 // ความกว้างของจอแสดงผล OLED เป็นพิกเซล #define SCREEN_HEIGHT 64 // ความสูงของจอแสดงผล OLED เป็นพิกเซล // การประกาศสำหรับจอแสดงผล SSD1306 ที่เชื่อมต่อโดยใช้ซอฟต์แวร์ SPI (ตัวพิมพ์เริ่มต้น): # กำหนด OLED_MOSI D7 # กำหนด OLED_CLK D5 # กำหนด OLED_DC D2 # กำหนด OLED_CS D8 # กำหนด OLED_RESET D3
จอแสดงผล Adafruit_SSD1306 (SCREEN_WIDTH, SCREEN_HEIGHT, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
แทนที่“ your_ssid” และ“ your_password” ด้วย Wi-Fi SSID และรหัสผ่านในบรรทัดด้านล่างของโค้ด
const ถ่าน * ssid = "your_ssid"; const ถ่าน * รหัสผ่าน = "your_password";
ตั้งค่าการเชื่อมต่อ WI-Fi โดยกำหนด SSID และรหัสผ่านให้กับฟังก์ชัน WiFi.begin การเชื่อมต่อ ESP8266 ใช้เวลาพอสมควรในการเชื่อมต่อกับ NodeMCU ดังนั้นเราจึงต้องรอจนกว่าจะเชื่อมต่อ
WiFi.begin (ssid รหัสผ่าน); ในขณะที่ (WiFi.status ()! = WL_CONNECTED) { ล่าช้า (500); Serial.print ("."); }
ในวันที่มีการร้องขอและเวลาเริ่มต้นของลูกค้าเวลาที่มีอยู่ของเซิร์ฟเวอร์ NTP เพื่อความแม่นยำที่ดีกว่าให้เลือกที่อยู่ของเซิร์ฟเวอร์ NTP ที่อยู่ใกล้กับพื้นที่ทางภูมิศาสตร์ของคุณ ที่นี่เราใช้“ pool.ntp.org ” ซึ่งให้บริการเซิร์ฟเวอร์จากทั่วโลก หากคุณต้องการเลือกเซิร์ฟเวอร์จากเอเชียคุณสามารถใช้“ asia.pool.ntp.org ” timeClient ยังใช้เวลาชดเชย UTC เป็นมิลลิวินาทีของเขตเวลาของคุณ ตัวอย่างเช่นUTC offset สำหรับอินเดียคือ +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 เริ่มต้นจะแสดงข้อความ“ ยินดีต้อนรับสู่วงจร DIGEST ” พร้อมข้อความขนาด 2 และสีฟ้าเป็นเวลา 3 วินาที
ถ้า (! display.begin (SSD1306_SWITCHCAPVCC)) { Serial.println (F ("การจัดสรร SSD1306 ล้มเหลว")); สำหรับ(;;); // อย่าดำเนินการวนซ้ำไปเรื่อย } display.clearDisplay (); display.setTextSize (2); // วาดข้อความขนาด 2X display.setTextColor (BLUE); display.setCursor (5, 2); display.println ("ยินดีต้อนรับสู่"); display.println ("CIRCUIT"); display.println ("DIGEST"); display.display (); ล่าช้า (3000);
ไคลเอนต์ NTP เริ่มต้นโดยใช้ ฟังก์ชัน start () เพื่อตั้งค่าวันที่และเวลาจากเซิร์ฟเวอร์ 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 = timeClient.getDay (); ถ้า (hh> 12) { hh = hh-12; display.print (hh); display.print (":"); display.print (มม.); display.print (":"); display.print (เอสเอส); display.println ("น."); } else { display.print (hh); display.print (":"); display.print (มม.); display.print (":"); display.print (เอสเอส); display.println ("AM"); } วัน int = timeClient.getDay (); display.println ("'" + arr_days + "'");
getFormattedDate () ใช้รับวันที่ในรูปแบบ “ yyyy-mm-dd” จากเซิร์ฟเวอร์ NTP ฟังก์ชั่นนี้จะช่วยให้วันและเวลาในการ “YYYY-MM-DD HH T: mm: ss รูปแบบ แต่เราต้องการวันที่เท่านั้นดังนั้นเราจึงต้องแยกสตริงนี้ซึ่งเก็บไว้ในรูปแบบ date_time จนถึง“ T” ซึ่งทำโดยฟังก์ชัน สตริงย่อย () แล้วเก็บวันที่ไว้ในตัวแปร “ วันที่”
date_time = timeClient.getFormattedDate (); int index_date = date_time.indexOf ("T"); วันที่สตริง = date_time.substring (0, index_date); Serial.println (วันที่); display.println (วันที่); display.display ();
นี่คือลักษณะของนาฬิกาเวลาอินเทอร์เน็ต OLEDในที่สุด: