เนื้อหาในบทความ
แนะนำ
ยุคแห่ง Smart Home มาถึงแล้ว! การปรับปรุงบ้านให้เป็นอัจฉริยะไม่จำเป็นต้องใช้เงินลงทุนสูงหรือจ้างช่างมืออาชีพ ด้วย ESP32 และ CynoIoT Platform คุณสามารถสร้างสวิตช์ไฟอัจฉริยะควบคุมด้วยมือถือได้ด้วยตัวเองในราคาไม่ถึง 500 บาท
ในบทความนี้คุณจะได้เรียนรู้:
- วิธีการต่อวงจร Relay ควบคุมไฟ AC 220V อย่างปลอดภัย
- เขียนโค้ด ESP32 เชื่อมต่อ WiFi และ CynoIoT Cloud
- สร้าง Dashboard ควบคุมไฟผ่านมือถือได้ฟรี
- ติดตั้งและใช้งานได้จริงในบ้าน
⚠️ คำเตือนความปลอดภัย: โปรเจกต์นี้เกี่ยวข้องกับไฟฟ้ากระแสสลับ (AC) 220V ซึ่งอันตรายถึงชีวิต หากคุณไม่มีประสบการณ์ แนะนำให้ใช้มัลติมิเตอร์ทดสอบก่อนต่อใช้จริง หรือใช้โมดูล Relay ที่มีระบบป้องกันไฟกระแสสูง
คุณสมบัติของโปรเจกต์
📱 ควบคุมผ่านมือถือ
เปิด-ปิดไฟได้จากทุกที่ ทุกเวลา ด้วยแอปบนมือถือ
🌐 เชื่อมต่อ CynoIoT Cloud
บันทึกข้อมูลการใช้งาน ตั้งเวลา และ Automation
🕐 ตั้งเวลาอัตโนมัติ
Schedule ไฟเปิด-ปิดตามเวลาที่กำหนด
💡 ประหยัดพลังงาน
ตรวจสอบการใช้งานไฟและปิดเมื่อไม่ใช้
อุปกรณ์ที่ต้องใช้
Hardware:
- ESP32 DevKitC หรือ ESP32 board อื่นๆ (1 บอร์ด) - ~120 บาท
- Relay Module 5V (1-4 ช่อง ขึ้นอยู่กับจำนวนไฟ) - ~50-150 บาท
- Jumper Wires (Female-to-Male และ Male-to-Male)
- Breadboard (สำหรับทดสอบ) - ~30 บาท
- Power Supply 5V 2A (สำหรับ ESP32 และ Relay)
- AC Load (หลอดไฟ ปลั๊กไฟ หรืออุปกรณ์ที่ต้องการควบคุม)
Software & Tools:
- Arduino IDE (พร้อม ESP32 Board Package)
- CynoIoT Account (สมัครฟรีที่ cynoiot.com)
- USB Cable (Micro-USB หรือ USB-C สำหรับ ESP32)
💡 เคล็ดลับ: แนะนำให้ใช้ Relay Module ที่มี Optocoupler ภายใน เพื่อความปลอดภัยและแยกวงจร AC ออกจาก ESP32
วงจรและการต่อสาย
วงจร DC (ESP32 และ Relay):
| ESP32 Pin | Relay Module |
|---|---|
| GPIO 26 (หรือ D26) | IN1 (Input 1) |
| GPIO 27 (หรือ D27) | IN2 (Input 2 - ถ้ามี) |
| GND | GND |
| VIN (5V) | VCC |
วงจร AC (ไฟ 220V):
⚠️ อันตราย! ไฟฟ้ากระแสสลับ 220V อันตรายถึงชีวิต ห้ามต่อวงจรขณะไฟเปิดอยู่!
- ต่อสาย Phase (L) จากปลั๊กไฟเข้า COM บน Relay
- ต่อสายจาก NO (Normally Open) ออกไปยังหลอดไฟ/อุปกรณ์
- ต่อสาย Neutral (N) ตรงจากปลั๊กไฟไปยังหลอดไฟ/อุปกรณ์โดยไม่ผ่าน Relay
- ต่อสาย Ground (PE) ถ้ามีช่องระบายไฟฟ้าสถิต
📌 หมายเหตุ:
- Relay มี 3 ขา: COM (Common), NO (Normally Open), NC (Normally Closed)
- เราใช้ NO เพื่อให้ไฟดับเมื่อ Relay ไม่ทำงาน (ปลอดภัยกว่า)
- ใช้มัลติมิเตอร์ทดสอบวงจร DC ก่อนต่อไฟ AC จริง
การติดตั้ง Software
1. ติดตั้ง Arduino IDE และ ESP32 Board:
// เปิด Arduino IDE
// ไปที่ File > Preferences
// ในช่อง "Additional Board Manager URLs" ใส่:
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
// ไปที่ Tools > Board > Boards Manager
// ค้นหา "esp32" และติดตั้ง "esp32 by Espressif Systems"2. ติดตั้ง Library ที่จำเป็น:
// ไปที่ Sketch > Include Library > Manage Libraries
// ติดตั้ง Library เหล่านี้:
// - WiFi (ESP32 built-in)
// - WebServer (ESP32 built-in)
// - ArduinoJson (เวอร์ชัน 6.x)3. สมัคร CynoIoT Account:
- เข้าไปที่ cynoiot.com
- คลิก "Sign Up" และกรอกข้อมูล
- ยืนยันอีเมลและล็อกอิน
- สร้าง Device ใหม่ใน Dashboard (จะได้ Device ID และ API Key)
โค้ด ESP32
นี่คือโค้ดที่สมบูรณ์สำหรับ ESP32 Smart Switch ที่เชื่อมต่อกับ CynoIoT:
/*
* ESP32 Smart Switch with CynoIoT
* ควบคุมไฟผ่าน CynoIoT Platform
*
* Hardware: ESP32 + Relay Module
* Author: CynoIoT
* Date: March 2026
*/
#include <WiFi.h>
#include <WebServer.h>
#include <ArduinoJson.h>
#include <HTTPClient.h>
// ================== การตั้งค่า WiFi ==================
const char* ssid = "YOUR_WIFI_SSID"; // ชื่อ WiFi ของคุณ
const char* password = "YOUR_WIFI_PASSWORD"; // รหัส WiFi
// ================== การตั้งค่า CynoIoT ==================
const char* cynoiot_server = "api.cynoiot.com";
const String device_id = "YOUR_DEVICE_ID"; // Device ID จาก CynoIoT
const String api_key = "YOUR_API_KEY"; // API Key จาก CynoIoT
// ================== การตั้งค่า GPIO ==================
const int RELAY_PIN_1 = 26; // GPIO สำหรับ Relay ช่องที่ 1
const int RELAY_PIN_2 = 27; // GPIO สำหรับ Relay ช่องที่ 2 (ถ้ามี)
// ================== ตัวแปรสถานะ ==================
bool relay1_state = false;
bool relay2_state = false;
unsigned long last_check_time = 0;
const long check_interval = 5000; // ตรวจสอบทุก 5 วินาที
WebServer server(80);
// ฟังก์ชันเริ่มต้น
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("\n=== ESP32 Smart Switch - CynoIoT ===");
// ตั้งค่า GPIO pins
pinMode(RELAY_PIN_1, OUTPUT);
pinMode(RELAY_PIN_2, OUTPUT);
digitalWrite(RELAY_PIN_1, LOW); // เริ่มต้นให้ปิด Relay
digitalWrite(RELAY_PIN_2, LOW);
Serial.println("✓ GPIO initialized");
// เชื่อมต่อ WiFi
connectWiFi();
// ตั้งค่า Web Server
setupWebServer();
Serial.println("✓ System ready!");
Serial.println("Relay 1: OFF | Relay 2: OFF");
}
// ลูปหลัก
void loop() {
server.handleClient();
// ตรวจสอบคำสั่งจาก CynoIoT ทุก 5 วินาที
if (millis() - last_check_time >= check_interval) {
last_check_time = millis();
checkCynoIoTCommands();
}
}
// เชื่อมต่อ WiFi
void connectWiFi() {
Serial.print("Connecting to WiFi...");
WiFi.begin(ssid, password);
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 20) {
delay(500);
Serial.print(".");
attempts++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\n✓ WiFi connected!");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
} else {
Serial.println("\n✗ Failed to connect to WiFi");
Serial.println("Retrying in 5 seconds...");
delay(5000);
connectWiFi(); // ลองใหม่
}
}
// ตั้งค่า Web Server
void setupWebServer() {
// หน้าแรก - Dashboard
server.on("/", HTTP_GET, handleRoot);
// API สำหรับควบคุม Relay
server.on("/api/relay", HTTP_POST, handleRelayControl);
// API สำหรับตรวจสอบสถานะ
server.on("/api/status", HTTP_GET, handleStatus);
server.begin();
Serial.println("✓ Web server started on port 80");
}
// หน้า Dashboard
void handleRoot() {
String html = "<!DOCTYPE html>";
html += "<html lang='th'>";
html += "<head>";
html += "<meta charset='UTF-8'>";
html += "<meta name='viewport' content='width=device-width, initial-scale=1.0'>";
html += "<title>ESP32 Smart Switch</title>";
html += "<style>";
html += "body{font-family:Arial,sans-serif;margin:20px;background:#f5f5f5;}";
html += ".container{max-width:600px;margin:0 auto;background:#fff;padding:20px;border-radius:10px;box-shadow:0 2px 10px rgba(0,0,0,0.1);}";
html += "h1{text-align:center;color:#333;}";
html += ".relay-box{border:1px solid #ddd;padding:15px;margin:10px 0;border-radius:5px;}";
html += ".relay-box h3{margin:0 0 10px 0;color:#666;}";
html += ".button-group{display:flex;gap:10px;}";
html += "button{flex:1;padding:10px;border:none;border-radius:5px;cursor:pointer;font-size:16px;transition:0.3s;}";
html += ".btn-on{background:#4CAF50;color:#fff;}";
html += ".btn-on:hover{background:#45a049;}";
html += ".btn-off{background:#f44336;color:#fff;}";
html += ".btn-off:hover{background:#da190b;}";
html += ".status{text-align:center;padding:10px;margin:10px 0;border-radius:5px;font-weight:bold;}";
html += ".status.on{background:#d4edda;color:#155724;}";
html += ".status.off{background:#f8d7da;color:#721c24;}";
html += "</style>";
html += "</head>";
html += "<body>";
html += "<div class='container'>";
html += "<h1>🔌 ESP32 Smart Switch</h1>";
// Relay 1
html += "<div class='relay-box'>";
html += "<h3>Relay 1 (ไฟช่องที่ 1)</h3>";
html += "<div class='status " + String(relay1_state ? "on" : "off") + "'>";
html += relay1_state ? "สถานะ: เปิด (ON)" : "สถานะ: ปิด (OFF)";
html += "</div>";
html += "<div class='button-group'>";
html += "<button class='btn-on' onclick='toggleRelay(1, true)'>เปิด</button>";
html += "<button class='btn-off' onclick='toggleRelay(1, false)'>ปิด</button>";
html += "</div>";
html += "</div>";
// Relay 2
html += "<div class='relay-box'>";
html += "<h3>Relay 2 (ไฟช่องที่ 2)</h3>";
html += "<div class='status " + String(relay2_state ? "on" : "off") + "'>";
html += relay2_state ? "สถานะ: เปิด (ON)" : "สถานะ: ปิด (OFF)";
html += "</div>";
html += "<div class='button-group'>";
html += "<button class='btn-on' onclick='toggleRelay(2, true)'>เปิด</button>";
html += "<button class='btn-off' onclick='toggleRelay(2, false)'>ปิด</button>";
html += "</div>";
html += "</div>";
html += "</div>";
html += "<script>";
html += "function toggleRelay(relay, state){";
html += "fetch('/api/relay', {";
html += "method: 'POST',";
html += "headers: {'Content-Type': 'application/json'},";
html += "body: JSON.stringify({relay: relay, state: state})";
html += "}).then(() => setTimeout(() => location.reload(), 500));";
html += "}";
html += "</script>";
html += "</body>";
html += "</html>";
server.send(200, "text/html", html);
}
// ควบคุม Relay
void handleRelayControl() {
String body = server.arg("plain");
StaticJsonDocument<200> doc;
deserializeJson(doc, body);
int relay = doc["relay"];
bool state = doc["state"];
if (relay == 1) {
digitalWrite(RELAY_PIN_1, state ? HIGH : LOW);
relay1_state = state;
Serial.println("Relay 1: " + String(state ? "ON" : "OFF"));
} else if (relay == 2) {
digitalWrite(RELAY_PIN_2, state ? HIGH : LOW);
relay2_state = state;
Serial.println("Relay 2: " + String(state ? "ON" : "OFF"));
}
// ส่งข้อมูลกลับไปยัง CynoIoT
sendStateToCynoIoT();
server.send(200, "application/json", "{\"status\":\"ok\"}");
}
// ตรวจสอบสถานะ
void handleStatus() {
StaticJsonDocument<200> doc;
doc["relay1"] = relay1_state;
doc["relay2"] = relay2_state;
doc["wifi_rssi"] = WiFi.RSSI();
String response;
serializeJson(doc, response);
server.send(200, "application/json", response);
}
// ตรวจสอบคำสั่งจาก CynoIoT
void checkCynoIoTCommands() {
if (WiFi.status() != WL_CONNECTED) {
Serial.println("WiFi disconnected. Reconnecting...");
connectWiFi();
return;
}
HTTPClient http;
String url = "http://" + String(cynoiot_server) + "/api/devices/" + device_id + "/commands";
http.begin(url);
http.addHeader("Content-Type", "application/json");
http.addHeader("X-API-Key", api_key);
int httpCode = http.GET();
if (httpCode == 200) {
String payload = http.getString();
StaticJsonDocument<512> doc;
deserializeJson(doc, payload);
// ตรวจสอบคำสั่ง Relay 1
if (doc.containsKey("relay1")) {
bool new_state = doc["relay1"];
if (new_state != relay1_state) {
digitalWrite(RELAY_PIN_1, new_state ? HIGH : LOW);
relay1_state = new_state;
Serial.println("CynoIoT: Relay 1 = " + String(new_state ? "ON" : "OFF"));
}
}
// ตรวจสอบคำสั่ง Relay 2
if (doc.containsKey("relay2")) {
bool new_state = doc["relay2"];
if (new_state != relay2_state) {
digitalWrite(RELAY_PIN_2, new_state ? HIGH : LOW);
relay2_state = new_state;
Serial.println("CynoIoT: Relay 2 = " + String(new_state ? "ON" : "OFF"));
}
}
}
http.end();
}
// ส่งสถานะไปยัง CynoIoT
void sendStateToCynoIoT() {
if (WiFi.status() != WL_CONNECTED) return;
HTTPClient http;
String url = "http://" + String(cynoiot_server) + "/api/devices/" + device_id + "/state";
StaticJsonDocument<200> doc;
doc["relay1"] = relay1_state;
doc["relay2"] = relay2_state;
String payload;
serializeJson(doc, payload);
http.begin(url);
http.addHeader("Content-Type", "application/json");
http.addHeader("X-API-Key", api_key);
http.POST(payload);
http.end();
}💡 อย่าลืม: เปลี่ยน YOUR_WIFI_SSID, YOUR_WIFI_PASSWORD, YOUR_DEVICE_ID และ YOUR_API_KEY ให้เป็นของคุณเอง
เชื่อมต่อ CynoIoT
1. สร้าง Device ใน CynoIoT:
- ล็อกอินที่ cynoiot.com
- ไปที่ "My Devices" > "Add New Device"
- ตั้งชื่อ Device (เช่น "Smart Switch - Living Room")
- เลือก Device Type: "Smart Switch"
- คัดลอก Device ID และ API Key
2. อัปโหลดโค้ดไปยัง ESP32:
- เปิด Arduino IDE และวางโค้ดด้านบน
- แก้ไข WiFi credentials และ CynoIoT credentials
- เลือก Board: "ESP32 Dev Module"
- เลือก Port: พอร์ต USB ที่ ESP32 เชื่อมต่ออยู่
- คลิก "Upload" หรือกด Ctrl+U
- เปิด Serial Monitor (Ctrl+Shift+M) เพื่อดูสถานะ
✅ ถ้าเห็น "✓ System ready!" ใน Serial Monitor แสดงว่าเชื่อมต่อสำเร็จ!
แอปควบคุมมือถือ
หลังจากเชื่อมต่อ ESP32 กับ CynoIoT แล้ว คุณสามารถควบคุมได้ผ่าน:
📱 CynoIoT Mobile App
- ดาวน์โหลดฟรีบน iOS และ Android
- ควบคุม Relay ได้ทันที
- ตั้งเวลา Automation
- ดูประวัติการใช้งาน
🌐 Web Dashboard
- เข้าถึงได้จากคอมพิวเตอร์หรือมือถือ
- ไม่ต้องติดตั้งแอป
- ใช้งานได้ทันทีบนเบราว์เซอร์
🎯 ฟีเจอร์หลักในแอป:
- Instant Control: เปิด-ปิดไฟทันทีด้วยปุ่มเดียว
- Schedule: ตั้งเวลาเปิด-ปิดอัตโนมัติ
- Timer: นับถอยหลังปิดไฟอัตโนมัติ
- Energy Monitoring: ดูการใช้พลังงาน (ถ้ามีเซ็นเซอร์)
- Notifications: แจ้งเตือนเมื่อไฟเปิด/ปิด
ปัญหาที่พบบ่อย
ปัญหา: ESP32 เชื่อมต่อ WiFi ไม่ได้
สาเหตุ: ชื่อ WiFi หรือรหัสผ่านผิด ระยะห่างไกลเกินไป หรือ Router ไม่รองรับ 2.4GHz
วิธีแก้: ตรวจสอบชื่อและรหัส WiFi ใกล้ Router หรือใช้ WiFi Extender
ปัญหา: Relay ทำงานไม่ตรงกับปุ่ม
สาเหตุ: ต่อสายผิดขา หรือ Relay เสีย
วิธีแก้: ตรวจสอบวงจรตาม Diagram ทดสอบ Relay ด้วยมัลติมิเตอร์
ปัญหา: CynoIoT ไม่ได้รับข้อมูล
สาเหตุ: Device ID หรือ API Key ผิด หรืออินเทอร์เน็ตไม่เสถียร
วิธีแก้: ตรวจสอบ Credentials ตรวจสอบ Serial Monitor ดู Error message
ปัญหา: ESP32 รีสตาร์ทบ่อย
สาเหตุ: ไฟเลี้ยงไม่เพียงพอ หรือวงจรลัดวงจร (Short circuit)
วิธีแก้: ใช้ Power Supply 5V 2A ตรวจสอบวงจรว่าลัดหรือไม่
สรุป
ยินดีด้วย! คุณได้สร้างระบบ Smart Switch ด้วย ESP32 และ CynoIoT สำเร็จแล้ว ตอนนี้คุณสามารถควบคุมไฟในบ้านผ่านมือถือได้แล้ว
สิ่งที่คุณได้เรียนรู้:
- การต่อวงจร Relay ควบคุมไฟ AC อย่างปลอดภัย
- เขียนโค้ด ESP32 เชื่อมต่อ WiFi และ Cloud
- สร้าง Web Server ควบคุม Relay บน ESP32
- เชื่อมต่อกับ CynoIoT Platform และควบคุมผ่านมือถือ
ถัดไป:
- เพิ่มเซ็นเซอร์วัดกระแสไฟ (ACS712) เพื่อตรวจสอบการใช้พลังงาน
- เพิ่มปุ่ม Physical Switch ที่ตัวเครื่อง
- ต่อขยายเป็น 4-8 ช่อง สำหรับควบคุมไฟทั้งห้อง
- สร้าง Automation เช่น "เปิดไฟเมื่อมีคนเข้าห้อง"
🔗 บทความที่เกี่ยวข้อง:
Arduino Nano ESP32 Getting Started • Weather Station Tutorial