ผู้เขียน หัวข้อ: งานครั้งที่ 25 [On Line] การดึงเวลาจากเซิร์ฟเวอร์ (เวลาสากล) มาใช้งาน  (อ่าน 8664 ครั้ง)

admin

  • Administrator
  • Hero Member
  • *****
  • กระทู้: 706
    • ดูรายละเอียด
    • อีเมล์
การดึงเวลาจากเซิร์ฟเวอร์มาใช้งาน
  โครงงานบางโครงงานที่ต้องการทำงานอัตโนมัติที่เกี่ยวข้องกับเวลา เช่น เครื่องรดน้ำต้นไม้ เครื่องให้อาหารปลา โครงงานเหล่านี้จะต้องใช้เวลาเป็นตัวกำหนดการทำงานซึ่งไมโครคอนโทรลเลอร์ทั่ว ๆ ไปสามารถทำได้โดยปกติอยู่แล้ว ซึ่งอาจใช้การเขียนเป็นโปรแกรมนับเวลาหรือจะใช้โมดูลเก็บเวลาจริงที่เรียกว่า RTC เป็นตัวเก็บเวลาแล้วทำการเขียนโปรแกรมดึงเวลาเข้ามาประมวลผล NodeMCU เป็นไมโครคอนโทรลเลอร์ตัวหนึ่งที่สามารถเชื่อมต่ออินเตอร์เน็ตได้ ดังนั้นเมื่อเชื่อมต่ออินเตอร์เน็ตได้ก็สามารถที่จะดึงเวลาจากเซิร์ฟเวอร์มาใช้งานได้ ซึ่งจะมีข้อดีกว่าการใช้ RTC อยู่สองสามประการได้แก่ประหยัดเงินซื้อโมดูล RTC และเวลาที่ได้จากเซิร์เวอร์จะเที่ยงตรงเสมอ ซึ่งถ้าใช้งาน RTC เวลาจะคลาดเคลื่อนได้เมื่อใช้งานไประยะหนึ่งซึ่งผู้ใช้งานจะต้องมาตั้งค่าเวลาให้กับ RTC ใหม่

ไลบรารี่ที่นำมาใช้งานคือ Time.h ซึ่งมีตัวแปรส่งค่าต่าง ๆ ในรูปแบบ  Struct ดังนี้
โค๊ด: [Select]
struct tm {
   int tm_sec;         /* วินาที,  range 0 to 59          */
   int tm_min;         /* นาที, range 0 to 59           */
   int tm_hour;        /* ชั่วโมง, range 0 to 23             */
   int tm_mday;        /* วันที่, range 1 to 31  */
   int tm_mon;         /* เดือน, range 0 to 11             */
   int tm_year;        /* ปีคริสศักราช ตั้งแต่ 1900   */
   int tm_wday;        /* วัน, range 0 to 6    */
   int tm_yday;        /* วันใน 1 ปี, range 0 to 365  */
   int tm_isdst;       /* daylight saving time             */
};

โจทย์โปรแกรม
-เขียนโปรแกรมดึงเวลาจากเซิร์ฟเวอร์มาควบคุม LED ติด/ดับ ตามวันเวลาที่กำหนดไว้
-โปรแกรมรายละเอียดพิเศษรายกลุ่ม (แจ้งให้ทราบเมื่อถึงชั่วโมงเรียน)


วงจรที่ใช้ในการทดลอง


ตัวอย่างโปรแกรม 1
โค๊ด: [Select]
#include <ESP8266WiFi.h>
#include <time.h>

const char* ssid = "Your SSID";             // SSID is set
const char* password = "Your password";     // Password is set

char ntp_server1[20] = "pool.ntp.org";
char ntp_server2[20] = "time.nist.gov";
char ntp_server3[20] = "time.uni.net.th";

int timezone = 7 * 3600;
int dst = 0;

void setup() {
  Serial.begin(115200);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println(WiFi.localIP());
  Serial.println("");

  configTime(timezone, dst, ntp_server1, ntp_server2, ntp_server3);
  Serial.println("\nWaiting for 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.println(p_tm->tm_sec);
  Serial.println(ctime(&now)); 
  delay(1000);
}
ตัวอย่างโปรแกรม 2 (การรวมทุกค่าลงในตัวแปรเดียว)
โค๊ด: [Select]
#include <ESP8266WiFi.h>
#include <time.h>

const char* ssid = "Your SSID";             // SSID is set
const char* password = "Your password";     // Password is set

char ntp_server1[20] = "pool.ntp.org";
char ntp_server2[20] = "time.nist.gov";
char ntp_server3[20] = "time.uni.net.th";

int timezone = 7*3600;
int dst = 0;
 
void setup() {
  Serial.begin(115200);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");     
  Serial.println(WiFi.localIP()); 
  Serial.println(""); 

  configTime(timezone, dst, ntp_server1, ntp_server2, ntp_server3);
  Serial.println("\nWaiting for time");
  while (!time(nullptr)) {
    Serial.print(".");
    delay(1000);
  }
  Serial.println("");
}

void loop() {
  Serial.println(NowTime());
  delay(1000);
}
String NowTime() {
  time_t now = time(nullptr);
  struct tm* p_tm=localtime(&now);
  String timeNow = "";
  timeNow += String(p_tm->tm_hour);
  timeNow += ":";
  timeNow += String(p_tm->tm_min);
  timeNow += ":";
  timeNow += String(p_tm->tm_sec);
  timeNow += " ";
  timeNow += String(p_tm->tm_mday);
  timeNow += "-";
  timeNow += String(p_tm->tm_mon + 1);
  timeNow += "-"; 
  timeNow += String(p_tm->tm_year + 1900);
  return timeNow;
}
ตัวอย่างโปรแกรม 3 (ใช้ไลบรารี่ WiFiManager)
โค๊ด: [Select]
#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>
#include <time.h>

int timezone = 7*3600;
int dst = 0;

void setup() {
    Serial.begin(115200);
    Serial.setDebugOutput(true);
    Serial.println("Starting...");

    WiFiManager wifiManager;
    wifiManager.setTimeout(180);
    if(!wifiManager.autoConnect("NodeMCU-Config")) {
      Serial.println("Failed to connect and hit timeout");
      delay(3000);
      ESP.reset();
      delay(5000);
    }
   
    configTime(timezone, dst, "pool.ntp.org", "time.nist.gov");
    Serial.println("\nWaiting for time");
    while (!time(nullptr)) {
    Serial.print(".");
    delay(1000);
  }
  Serial.println("");

}
void loop() {
  time_t now = time(nullptr);
  struct tm* p_tm=localtime(&now);
 
  Serial.println(ctime(&now));
  Serial.print(p_tm->tm_hour);Serial.print(":");
  Serial.print(p_tm->tm_min);Serial.print(":");
  Serial.println(p_tm->tm_sec);
  delay(1000);
}
ผลการรันเมื่อ NodeMCU ติดต่อกับอินเตอร์เน็ตและดึงเวลาจากเซิร์ฟเวอร์ได้

เครดิต Comdet Phudphut แห่งขอนแก่นเมคเกอร์คลับ
https://www.youtube.com/watch?v=c8MpndNKOTs
« แก้ไขครั้งสุดท้าย: สิงหาคม 22, 2018, 11:36:34 AM โดย admin »