การดึงค่าเวลามาตรฐานสากลจากอินเตอร์เน็ต จะดึงจาก Server ที่ให้บริการโพรโทคอล NTP โดย NTP Server มีอยู่ด้วยกันหลายที่ คำว่า "NTP” จาก https://www.thaicert.or.th/papers/technical/2014/pa2014te002.html ได้อธิบายความหมายของ ว่า “NTP หรือที่ย่อมาจากคำว่า Network Time Protocol เป็นโพรโทคอลสำหรับการเทียบเวลามาตรฐานและตั้งค่าเวลาบนเครื่องคอมพิวเตอร์นั้นๆผ่านระบบเครือข่าย ส่วนใหญ่ถูกนำมาใช้ในองค์กรเพื่อช่วยทำให้เวลาในเครื่องคอมพิวเตอร์หรือเครื่องแม่ข่ายนั้นมีค่าตรงกัน โดยรูปแบบการทำงานนั้นแบ่งเป็น 2 ส่วนหลักๆคืออุปกรณ์ที่ให้บริการเทียบเวลา (NTP Server) กับเครื่องคอมพิวเตอร์หรืออุปกรณ์ที่ต้องการเทียบเวลา (NTP Client) โดยโพรโทคอล NTP นั้นเชื่อมต่อผ่านทางระบบเครือข่ายด้วยโพรโทคอล UDP ผ่านพอร์ต 123 (โพรโทคอล UDP มีความรวดเร็วในการรับส่งข้อมูลแต่ก็มีข้อเสียตรงที่โพรโทคอล UDP ไม่มีการตรวจสอบความถูกต้องของข้อมูลที่รับส่งกันอยู่เหมือน TCP)” วัตถุประสงค์ ใช้ ESP8266 NodeMCU สร้าง Station เพื่อดึงค่าเวลามาตรฐานจาก NTP Server แล้วแสดงผลทาง Serial monitor
อุปกรณ์
ตัวอย่างโปรแกรม ใช้ไลบรารี Time.h และใช้ ฟังก์ชั่นมาตรฐาน localtime() or gmtime() and the struct tm. เพื่อดึงค่าเป็น วัน-เดือน-ปี ชม- นาที และ วินาที ค่าที่ดึงได้นี้จะเป็นตัวเลข ใช้การแปลงจากตัวเลขวัน ตัวเลขเดือน ให้เป็นชื่อเดือน ชื่อวัน ส่วนปี ค.ศ. เปลี่ยนเป็นปี พ.ศ.
โปรแกรม time_ntp3.ino
#include <ESP8266WiFi.h> #include <Time.h>
const char* ssid = "TOT"; // your network SSID (name) const char* password = "0815610067"; // your network password const String month_name[12] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}; const String day_name[7] = {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
int timezone = 7 * 3600; //ตั้งค่า TimeZone ตามเวลาประเทศไทย int dst = 0; //กำหนดค่า Date Swing Time
void setup() { Serial.begin(115200); Serial.setDebugOutput(true);
WiFi.mode(WIFI_STA); //เชื่อมต่อ Wifi WiFi.begin(ssid, password); Serial.println(" Connecting to WiFi"); while (WiFi.status() != WL_CONNECTED) { Serial.print("*"); delay(1000); } configTime(timezone, dst, "pool.ntp.org", "time.nist.gov"); //ดึงเวลาจาก Server Serial.println(" Loading time"); while (!time(nullptr)) { Serial.print("*"); delay(1000); } Serial.println(""); }
void loop() { //แสดงเวลาปัจจุบัน time_t now = time(nullptr); struct tm* p_tm = localtime(&now); Serial.print(p_tm->tm_hour); Serial.print(":"); Serial.print(p_tm->tm_min); Serial.print(":"); Serial.print(p_tm->tm_sec);
Serial.print(" / "); Serial.print(day_name[(p_tm->tm_wday)]); Serial.print("/"); Serial.print(p_tm->tm_mday); Serial.print(" / "); Serial.print(month_name[(p_tm->tm_mon)]); Serial.print(" / "); Serial.print(p_tm->tm_year + 2443); Serial.println("");
delay(1000); }
ความหมาย 1. configTime จาก https://github.com/esp8266/Arduino/blob/9913e5210779d2f3c4197760d6813270dbba6232/cores/esp8266/time.c#L58 มีรายละเอียดดังนี้
void configTime(int timezone, int daylightOffset_sec, const char* server1, const char* server2, const char* server3) { sntp_stop();
setServer(0, server1); setServer(1, server2); setServer(2, server3);
sntp_set_timezone(timezone/3600); sntp_set_daylight(daylightOffset_sec); sntp_init(); }
int timezone = 7 * 3600;
ตัวอย่าง configTime(timezone, dst, "time.navy.mi.th"); 2. โครงสร้างของตัวแปร tm มีดังนี้
|