การเรียกใช้เวลามาตรฐาน NTP ด้วย ESP32
โปรเจคที่ต้องการทำงานอัตโนมัติที่เกี่ยวข้องกับเวลา เช่น เครื่องรดน้ำต้นไม้ เครื่องให้อาหารปลา โปรเจคเหล่านี้จะต้องใช้เวลาเป็นตัวกำหนดการทำงานซึ่งไมโครคอนโทรลเลอร์ทั่ว ๆ ไปสามารถทำได้โดยปกติอยู่แล้ว ซึ่งอาจใช้การเขียนเป็นโปรแกรมนับเวลาหรือจะใช้โมดูลเก็บเวลาจริงที่เรียกว่า RTC เป็นตัวเก็บเวลาแล้วทำการเขียนโปรแกรมดึงเวลาเข้ามาประมวลผล ESP32 เป็นไมโครคอนโทรลเลอร์ตัวหนึ่งที่สามารถเชื่อมต่ออินเตอร์เน็ตได้ ดังนั้นเมื่อเชื่อมต่ออินเตอร์เน็ตได้ก็สามารถที่จะดึงเวลาจากเซิร์ฟเวอร์มาใช้งานได้ ซึ่งจะมีข้อดีกว่าการใช้ RTC อยู่สองสามประการได้แก่ประหยัดเงินซื้อโมดูล RTC และเวลาที่ได้จากเซิร์เวอร์จะเที่ยงตรงเสมอ ซึ่งถ้าใช้งาน RTC เวลาจะคลาดเคลื่อนได้เมื่อใช้งานไประยะหนึ่งซึ่งผู้ใช้งานจะต้องมาตั้งค่าเวลาให้กับ RTC ใหม่
ตัวอย่างโปรเจคที่ใช้ RTC
ดึงเวลาสากล จาก internet มาใช้งานกับ ESP32
การรับวันที่และเวลาจากเซิร์ฟเวอร์ NTP ด้วย ESP32 หรือการดึงค่าเวลามาตรฐานสากลจากอินเตอร์เน็ต จะดึงจาก Server ที่ให้บริการโพรโทคอล NTP โดย NTP Server มีอยู่ด้วยกันหลายที่ คำว่า “NTP” ย่อมาจากคำว่า Network Time Protocol เป็นโพรโทคอลสำหรับการเทียบเวลามาตรฐานและตั้งค่าเวลาบนเครื่องคอมพิวเตอร์นั้นๆผ่านระบบเครือข่าย ส่วนใหญ่ถูกนำมาใช้ในองค์กรเพื่อช่วยทำให้เวลาในเครื่องคอมพิวเตอร์หรือเครื่องแม่ข่ายนั้นมีค่าตรงกัน โดยรูปแบบการทำงานนั้นแบ่งเป็น 2 ส่วนหลักๆคืออุปกรณ์ที่ให้บริการเทียบเวลา (NTP Server) กับเครื่องคอมพิวเตอร์หรืออุปกรณ์ที่ต้องการเทียบเวลา (NTP Client) โดยโพรโทคอล NTP นั้นเชื่อมต่อผ่านทางระบบเครือข่ายด้วยโพรโทคอล UDP ผ่านพอร์ต 123 (โพรโทคอล UDP มีความรวดเร็วในการรับส่งข้อมูลแต่ก็มีข้อเสียตรงที่โพรโทคอล UDP ไม่มีการตรวจสอบความถูกต้องของข้อมูลที่รับส่งกันอยู่เหมือน TCP
NTP ทำงานอย่างไร
NTP สามารถทำงานได้หลายวิธี การกำหนดค่าที่พบบ่อยที่สุดคือการทำงานในโหมดไคลเอนต์เซิร์ฟเวอร์ หลักการทำงานพื้นฐานมีดังนี้:
- อุปกรณ์ไคลเอนต์เช่น ESP32 เชื่อมต่อกับเซิร์ฟเวอร์โดยใช้ User Datagram Protocol (UDP) บนพอร์ต 123
- จากนั้นไคลเอนต์ส่งแพ็กเก็ตคำร้องขอไปยังเซิร์ฟเวอร์ NTP
- เพื่อตอบสนองต่อคำขอนี้เซิร์ฟเวอร์ NTP จะส่ง Time Stamp Packet
- Time Stamp Packet ประกอบด้วยข้อมูลหลายอย่างเช่น UNIX timestamp, accuracy, delay หรือ timezone.
- จากนั้นไคลเอนต์สามารถแยกวิเคราะห์ค่าวันที่และเวลาปัจจุบันได้
วัตถุประสงค์
ใช้ ESP32 สร้าง Station เพื่อดึงค่าเวลามาตรฐานจาก NTP Server แล้วแสดงผลทาง Serial Monitor
รายการอุปกรณ์
- 1. Keyestudio ESP32 Development Board ESP32-WROOM-32
- 2. Keyestudio ESP32-IO Shield
- 3. Micro USB Cable Wire 1m for NodeMCU
ขั้นตอนการทํางาน
1 : โปรแกรมแรก กับ Keyestudio ESP32
สวัสดีชาวโลก (Hello World) คือ คำง่าย ๆ สำหรับการเขียนโปรแกรมแรกของโปรแกรมเมอร์ เป็นโปรแกรมคอมพิวเตอร์พื้นฐานที่ทำการแสดงผลคำว่า “Hello world” บนอุปกรณ์แสดงผล ซึ่งเป็นหนึ่งในโปรแกรมที่ง่ายที่สุดเท่าที่จะเป็นไปได้ในการเขียนภาษาโปรแกรมต่างๆ ตามขั้นตอนลิงค์ด้านล่าง
2 : อัพโหลดโค้ดให้กับ Keyestudio ESP32
เปิดโปรแกรม Arduino IDE เขียนโปรแกรม หรือ Sketch ตามโค้ดด้านล่างนี้
#include <WiFi.h>
#include "time.h"
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASS";
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 7 * 3600;
const int daylightOffset_sec = 7 * 3600;
void printLocalTime()
{
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain time");
return;
}
Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}
void setup()
{
Serial.begin(115200);
//connect to WiFi
Serial.printf("Connecting to %s ", ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(" CONNECTED");
//init and get the time
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
printLocalTime();
//disconnect WiFi as it's no longer needed
WiFi.disconnect(true);
WiFi.mode(WIFI_OFF);
}
void loop()
{
delay(1000);
printLocalTime();
}
ก่อน อัพโหลดโค้ด มีค่าคงที่ต้องแก้ไข อยู่ 2 ค่าด้วยกันคือ
1. YOUR_SSID แก้เป็น ชื่อ WiFi ที่ต้องการเชื่อมต่อ
2. YOUR_PASS แก้เป็น รหัสผ่าน ของ WiFi ที่ต้องการเชื่อมต่อ
แล้วจึง อัพโหลดโค้ด
อธิบายโค้ด
มาดูโค้ดอย่างรวดเร็วเพื่อดูว่ามันทำงานอย่างไร ขั้นแรกเรารวมไลบรารีที่จำเป็นสำหรับโปรเจคนี้
- WiFi.h คือไลบรารี ที่มีวิธีการ WiFi เฉพาะของ ESP32 ที่เราเรียกเพื่อเชื่อมต่อกับเครือข่าย
- time.h คือไลบรารี native time library ซึ่งทำการซิงโครไนซ์กับเซิร์ฟเวอร์ NTP
#include <WiFi.h>
#include "time.h"
ต่อไปเราจะตั้งค่าค่าคงที่เช่น SSID, รหัสผ่าน WiFi, ที่คุณทราบอยู่แล้ว
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASS";
นอกจากนั้นเราจำเป็นต้องระบุที่อยู่ของเซิร์ฟเวอร์ NTP ที่เราต้องการใช้เช่น pool.ntp.org
const char* ntpServer = "pool.ntp.org";
UTC Offset & Daylight offset คุณต้องปรับค่าชดเชย UTC สำหรับเขตเวลาของคุณเป็นมิลลิวินาที โดยอ้างถึงการชดเชยเวลา UTC ตัวอย่างของเขตเวลา Time Zone ของกรุงเทพเป็น GMT+7 จึงเท่ากับ 7 * 3600
const long gmtOffset_sec = 7 * 3600;
const int daylightOffset_sec = 7 * 3600;
3 : ผลลัพธ์การทำงาน
เปิดหน้าต่าง Serial Monitor โดยไปที่ Tools -> Serial Monitor
ที่มุมขวาล่าง ของ Serial Monitor เลือกเป็น 115200 baud ที่ Serial Monitor จะแสดง วันที่และเวลาจากเซิร์ฟเวอร์ NTP
credit : https://lastminuteengineers.com/esp32-ntp-server-date-time-tutorial/