เนื้อหาในบทความ
ภาพรวมโปรเจกต์
นาฬิกาอัจฉริยะ (Smart Clock) คือโปรเจกต์ที่น่าสนใจและเป็นประโยชน์มาก โดยใช้ ESP32 เชื่อมต่อกับ WiFi เพื่อรับเวลาที่แม่นยำจาก NTP Server และแสดงผลบนจอแสดงผลดิจิทัล โปรเจกต์นี้เหมาะสำหรับการเรียนรู้การเขียนโปรแกรม IoT และการทำงานกับจอแสดงผล
ในบทความนี้ เราจะสร้างนาฬิกาที่สามารถ:
- ✓เชื่อมต่อ WiFi อัตโนมัติ
- ✓รับเวลาจาก NTP Server อัตโนมัติ
- ✓แสดงเวลาและวันที่บนจอ OLED
- ✓ตั้งค่า Timezone สำหรับประเทศไทย
- ✓ส่งข้อมูลไปยัง CynoIoT Platform
💡 ทำไมต้อง ESP32?
- •มี WiFi และ Bluetooth ในตัว
- •Dual-core processor ทำงานได้รวดเร็ว
- •รองรับ Library มากมายสำหรับจอแสดงผล
- •ราคาย่อมเยา (~100-150 บาท)
อุปกรณ์ที่ต้องใช้
Hardware List
- 1ESP32 Development Board (NodeMCU, Wemos, หรือ generic) - ~100-150 บาท
- 2OLED Display 0.96" (SSD1306, I2C) - ~80-120 บาท
- 3USB Cable - สำหรับเชื่อมต่อคอมพิวเตอร์และจ่ายไฟ
- 4Jumper Wires - สำหรับต่อวงจร (ถ้าจำเป็น)
- 5Breadboard (optional) - สำหรับทดลองต่อวงจร
💡 เคล็ดลับ: สามารถใช้จอแสดงผลประเภทอื่นได้ เช่น LCD 16x2, TFT 1.8", หรือ LED Matrix MAX7219 โดยอาจต้องปรับเปลี่ยน Code เล็กน้อย
เลือกจอแสดงผลที่เหมาะกับคุณ
มีจอแสดงผลหลายประเภทที่ใช้กับ ESP32 ได้ แต่ละอย่างมีข้อดีและข้อเสียที่แตกต่างกัน
🖥️ OLED 0.96" (SSD1306)
- • ขนาดเล็ก กระทัดรัด
- • ประหยัดไฟ
- • ความละเอียด 128x64
- • ราคา ~80-120 บาท
- ✓ เหมาะกับโปรเจกต์พกพา
📺 LCD 16x2 (I2C)
- • แสดงผลได้ 32 ตัวอักษร
- • อ่านง่าย ชัดเจน
- • ใช้ I2C (ต่อสายน้อย)
- • ราคา ~60-100 บาท
- ✓ เหมาะกับมือใหม่
🎨 TFT 1.8" (ST7735)
- • แสดงสีได้ 65,536 สี
- • ความละเอียด 128x160
- • สวยงาม ดูดี
- • ราคา ~150-200 บาท
- ✓ เหมาะกับ UI สวยๆ
🔢 LED Matrix (MAX7219)
- • ดูคลาสสิค เรโทร
- • สว่างมาก เห็นไกล
- • ต่อต่อกันหลายโมดูลได้
- • ราคา ~100-150 บาท
- ✓ เหมาะกับตกแต่งห้อง
ℹ️ คำแนะนำ: ในบทความนี้เราจะใช้ OLED 0.96" (SSD1306) เพราะเป็นที่นิยม ราคาไม่แพง และมี Library ที่ดี แต่คุณสามารถปรับเปลี่ยนเป็นจออื่นได้ตามต้องการ
เชื่อมต่อ WiFi ด้วย ESP32
ขั้นตอนแรกคือการเชื่อมต่อ ESP32 เข้ากับเครือข่าย WiFi เพื่อให้สามารถรับเวลาจากอินเทอร์เน็ตได้
#include <WiFi.h>
// ตั้งค่า WiFi credentials
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
// ฟังก์ชันเชื่อมต่อ WiFi
void connectToWiFi() {
Serial.print("Connecting to WiFi");
WiFi.begin(ssid, password);
// รอเชื่อมต่อ WiFi
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected!");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void setup() {
Serial.begin(115200);
connectToWiFi();
}
void loop() {
// ตรวจสอบสถานะ WiFi
if (WiFi.status() != WL_CONNECTED) {
connectToWiFi();
}
delay(10000);
}✅ ทดสอบ: อัปโหลดโค้ดและเปิด Serial Monitor (115200 baud) คุณควรเห็น IP address ของ ESP32 หลังจากเชื่อมต่อสำเร็จ
รับเวลาจาก NTP Server
NTP (Network Time Protocol) คือโปรโตคอลที่ใช้รับเวลาที่แม่นยำจาก Server ทำให้นาฬิกาของเราแม่นยำเหมือนเวลาอินเทอร์เน็ต
#include <WiFi.h>
#include <time.h>
// NTP Server สำหรับประเทศไทย
const char* ntpServer = "pool.ntp.org";
// Timezone สำหรับประเทศไทย (GMT+7)
const long gmtOffset_sec = 7 * 3600;
const int daylightOffset_sec = 0;
void setupTime() {
// ตั้งค่า NTP
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
Serial.println("Waiting for NTP time sync...");
// รอจนกว่าจะได้เวลา
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain time");
return;
}
Serial.println("Time synchronized!");
}
void printTime() {
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);
connectToWiFi(); // เชื่อมต่อ WiFi ก่อน
setupTime(); // ตั้งค่า NTP
}
void loop() {
printTime();
delay(1000); // แสดงเวลาทุกๆ 1 วินาที
}ℹ️ เข้าใจ Timezone: ประเทศไทยอยู่ใน GMT+7 ดังนั้น gmtOffset_sec = 7 * 3600 = 25200 วินาที ไม่มี Daylight Saving Time ดังนั้น daylightOffset_sec = 0
แสดงผลบนจอ OLED
ตอนนี้เราจะนำเวลาที่ได้จาก NTP มาแสดงผลบนจอ OLED โดยใช้ Library Adafruit_SSD1306
การต่อสาย OLED (I2C)
- •OLED VCC → ESP32 3.3V
- •OLED GND → ESP32 GND
- •OLED SCL → ESP32 GPIO 22
- •OLED SDA → ESP32 GPIO 21
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <WiFi.h>
#include <time.h>
// ขนาดจอ OLED
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
// สร้าง object สำหรับจอ OLED
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// WiFi credentials
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
// NTP settings
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 7 * 3600;
void setup() {
Serial.begin(115200);
// เริ่มต้นใช้งานจอ OLED
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("SSD1306 allocation failed");
for (;;);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
// เชื่อมต่อ WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
display.println("Connecting...");
display.display();
}
// ตั้งค่า NTP
configTime(gmtOffset_sec, 0, ntpServer);
}
void loop() {
struct tm timeinfo;
if (getLocalTime(&timeinfo)) {
display.clearDisplay();
// แสดงวันที่
display.setCursor(0, 0);
display.setTextSize(1);
display.println(&timeinfo, "%a, %d %b %Y");
// แสดงเวลา (ขนาดใหญ่)
display.setCursor(10, 25);
display.setTextSize(2);
display.println(&timeinfo, "%H:%M:%S");
display.display();
}
delay(1000); // อัปเดตทุกๆ 1 วินาที
}✅ ผลลัพธ์: หลังจากอัปโหลดโค้ด คุณจะเห็นเวลาและวันที่แสดงบนจอ OLED โดยอัปเดตทุกๆ 1 วินาที
เชื่อมต่อกับ CynoIoT Platform
นอกจากแสดงผลบนจอ OLED แล้ว เรายังสามารถส่งข้อมูลเวลาและสถานะไปยัง CynoIoT Platform เพื่อเก็บ log และตรวจสอบระยะไกล
🚀 วิธีการเชื่อมต่อ
- 1.สร้าง Device
สร้าง device ใหม่บน CynoIoT Platform และรับ Device ID และ API Key
- 2.ส่งข้อมูลผ่าน HTTP/MQTT
ใช้ HTTP POST หรือ MQTT Protocol ส่งข้อมูลเวลาและสถานะไปยัง Platform
- 3.ตรวจสอบข้อมูล
ดูข้อมูลที่ส่งไปบน Dashboard ของ CynoIoT
#include <HTTPClient.h>
#include <WiFi.h>
// CynoIoT API settings
const char* serverUrl = "https://api.cynoiot.com/v1/data";
const char* deviceId = "YOUR_DEVICE_ID";
const char* apiKey = "YOUR_API_KEY";
void sendDataToCynoIoT(float temperature, int uptime) {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin(serverUrl);
http.addHeader("Content-Type", "application/json");
http.addHeader("X-API-Key", apiKey);
// สร้าง JSON payload
String payload = "{";
payload += "device_id":" + String(deviceId) + "";
payload += ",\"timestamp":" + String(millis()) + "\";
payload += ",\"temperature":" + String(temperature) + "\";
payload += ",\"uptime":" + String(uptime) + "\";
payload += "}";
// ส่ง HTTP POST request
int httpCode = http.POST(payload);
if (httpCode > 0) {
Serial.println("Data sent successfully");
} else {
Serial.println("Error sending data");
}
http.end();
}
}
// ใช้ใน loop()
void loop() {
// ส่งข้อมูลทุกๆ 60 วินาที
static unsigned long lastSend = 0;
if (millis() - lastSend >= 60000) {
float temp = random(200, 300) / 10.0; // จำลองอุณหภูมิ
int uptime = millis() / 1000;
sendDataToCynoIoT(temp, uptime);
lastSend = millis();
}
}แนวคิดการปรับปรุงโปรเจกต์
⏰ ใส่ฟังก์ชันปลุก
เพิ่มปุ่มกดเพื่อตั้งเวลาปลุก และแสดงการแจ้งเตือนบนจอ OLED
🌡️ วัดอุณหภูมิ
เพิ่มเซ็นเซอร์ DHT22 เพื่อวัดอุณหภูมิ และแสดงบนจอพร้อมเวลา
📊 กราฟิกสวยๆ
ใช้จอ TFT แสดงกราฟิกเวลาแบบสวยงาม พร้อม animation
🔊 เสียงแจ้งเตือน
เพิ่ม Buzzer หรือ Speaker เพื่อส่งเสียง แจ้งเตือนตามเวลาที่ตั้ง
🎉 สรุป
ในบทความนี้คุณได้เรียนรู้:
- ✓การเลือกจอแสดงผลที่เหมาะกับโปรเจกต์
- ✓การเชื่อมต่อ ESP32 กับ WiFi
- ✓การรับเวลาจาก NTP Server
- ✓การแสดงผลบนจอ OLED
- ✓การเชื่อมต่อกับ CynoIoT Platform
นาฬิกาอัจฉริยะคือโปรเจกต์ที่เป็นประโยชน์และเรียนรู้ได้มาก สามารถนำไปปรับใช้กับจอแสดงผลประเภทอื่น หรือเพิ่มฟีเจอร์อื่นๆ ได้ตามต้องการ