📋 เนื้อหาในบทความ
🌧️ ภาพรวมโปรเจกต์
เคยเจอปัญหาน้ำฝนเข้าบ้านเพราะลืมปิดหน้าต่างไหม? ในฤดูฝนของไทย ฝนตกหนังหนังและมักจะตกในเวลาที่เราไม่อยู่บ้าน โปรเจกต์นี้จะช่วยแก้ปัญหานั้นด้วยการสร้างระบบตรวจจับฝนและปิดหน้าต่างอัตโนมัติเมื่อตรวจพบฝน
✨ จุดเด่นของโปรเจกต์
- • ตรวจจับฝนแบบ Real-time ด้วย Rain Sensor
- • ควบคุม Servo Motor ปิดหน้าต่างอัตโนมัติ
- • เชื่อมต่อ WiFi และส่งข้อมูลไป CynoIoT Platform
- • รับแจ้งเตือนผ่าน Application
- • ตรวจสอบสถานะระยะไกลได้ทุกที่ทุกเวลา
หลักการทำงาน
- Rain Sensor ตรวจจับน้ำฝนบนพื้นผิว
- เมื่อตรวจพับฝน → ESP32 ส่งสัญญาณไป Servo Motor
- Servo Motor หมุนเพื่อปิดหน้าต่าง
- ESP32 ส่งข้อมูลไป CynoIoT Platform ผ่าน WiFi
- ผู้ใช้รับแจ้งเตือนและตรวจสอบสถานะผ่านแอป
🛠️ อุปกรณ์ที่ต้องใช้
🔌 Hardware
- ✓ESP32 Development Board
แนะนำ: ESP32 DevKit V1 (~฿150)
- ✓Rain Sensor Module
แบบ analog/digital (~฿40)
- ✓Servo Motor (SG90 หรือ MG996R)
SG90 (~฿50) / MG996R (~฿120)
- ✓Jumper Wires
ตัวเมีย-ตัวเมีย 10 เส้น
- ✓Breadboard (ถ้าจำเป็น)
สำหรับทดสอบ (~฿30)
💻 Software & Tools
- ✓Arduino IDE
เวอร์ชัน 2.x ขึ้นไป
- ✓CynoIoT Account
สมัครฟรีที่ cynoiot.com
- ✓USB Cable
Micro USB สำหรับ ESP32
- ✓WiFi (2.4 GHz)
เน็ตบ้านหรือมือถือ hotspot
💰 งบประมาณรวม: ประมาณ ฿250-350 สำหรับอุปกรณ์ทั้งหมด
📦 สรุปรายการอุปกรณ์
| อุปกรณ์ | จำนวน | ราคาโดยประมาณ |
|---|---|---|
| ESP32 DevKit | 1 | ฿150 |
| Rain Sensor Module | 1 | ฿40 |
| Servo Motor SG90 | 1 | ฿50 |
| Jumper Wires | 1 แพ็ค | ฿20 |
| รวมทั้งหมด | - | ฿260 |
🔗 การต่อวงจร
Rain Sensor Module → ESP32
| Rain Sensor Pin | ESP32 Pin | หมายเหตุ |
|---|---|---|
| VCC | 3.3V | หรือ 5V ตาม Module |
| GND | GND | กราวด์ |
| AO (Analog Out) | GPIO 34 | สำหรับอ่านค่าแบบ analog |
| DO (Digital Out) | GPIO 35 | สำหรับอ่านค่าแบบ digital (ใช้ไม่ได้กับบางบอร์ด) |
⚠️ ข้อควรระวัง: GPIO 34-35 รองรับเฉพาะ Input เท่านั้น (Input-only) ห้ามใช้เป็น Output
Servo Motor → ESP32
| Servo Wire | ESP32 Pin | สีสาย (มาตรฐาน) |
|---|---|---|
| Signal | GPIO 18 | ส้ม/เหลือง |
| VCC | 5V (หรือ Vin) | แดง |
| GND | GND | น้ำตาล/ดำ |
💡 เคล็ดลับ: ถ้าใช้ MG996R (Servo ขนาดใหญ่) แนะนำให้จ่ายไฟจากแหล่งจ่ายภายนอก เพราะใช้กระแสสูงกว่าที่ ESP32 จ่ายได้
✅ ตรวจสอบการต่อวงจร
- • ตรวจสอบขา VCC และ GND ให้ถูกต้องก่อนเสียบไฟ
- • Rain Sensor วางบนพื้นผิวราบน้ำฝนจะไหลออกได้ดี
- • Servo Motor ติดตั้งให้แน่นกับหน้าต่าง
- • ใช้ Multimeter วัดแรงดันไฟเพื่อให้แน่ใจว่ามี 3.3V/5V
💻 การเขียนโค้ด
1. ติดตั้ง Library ที่จำเป็น
เปิด Arduino IDE ไปที่ Sketch → Include Library → Manage Libraries แล้วค้นหาและติดตั้ง:
- ESP32Servo สำหรับควบคุม Servo Motor
- WiFi มักจะมีมาให้อยู่แล้วกับ ESP32 Board Package
- HTTPClient สำหรับส่งข้อมูลไป CynoIoT
2. โค้ดหลัก (Rain Detection & Auto Window)
/*
* โปรเจกต์: ระบบตรวจจับฝนและปิดหน้าต่างอัตโนมัติ
* บอร์ด: ESP32 DevKit V1
* Rain Sensor: GPIO 34 (Analog)
* Servo Motor: GPIO 18
* แพลตฟอร์ม: CynoIoT
*/
#include <WiFi.h>
#include <ESP32Servo.h>
#include <HTTPClient.h>
// ================== การตั้งค่า WiFi ==================
const char* ssid = "YOUR_WIFI_SSID"; // แทนที่ด้วยชื่อ WiFi ของคุณ
const char* password = "YOUR_WIFI_PASSWORD"; // แทนที่ด้วยรหัส WiFi
// ================== การตั้งค่า CynoIoT ==================
const char* cynoiotServer = "api.cynoiot.com"; // เปลี่ยนตามความจริง
const char* deviceApiKey = "YOUR_DEVICE_API_KEY"; // API Key จาก CynoIoT
// ================== การตั้งค่า Hardware ==================
const int RAIN_SENSOR_PIN = 34; // GPIO 34 สำหรับ Rain Sensor (Analog)
const int SERVO_PIN = 18; // GPIO 18 สำหรับ Servo Motor
const int RAIN_THRESHOLD = 2000; // ค่า threshold (ปรับได้ 0-4095)
// ค่าต่ำ = ไม่มีฝน, ค่าสูง = มีฝน
// เซนเซอร์บางตัวให้ค่าตรงกันข้าม!
const int SERVO_OPEN_ANGLE = 0; // มุมเปิดหน้าต่าง (องศา)
const int SERVO_CLOSE_ANGLE = 90; // มุมปิดหน้าต่าง (องศา)
// ================== ตัวแปร ==================
Servo windowServo;
bool isRaining = false;
bool windowIsClosed = false;
unsigned long lastCheckTime = 0;
const unsigned long CHECK_INTERVAL = 2000; // ตรวจสอบทุก 2 วินาที
unsigned long lastSendTime = 0;
const unsigned long SEND_INTERVAL = 30000; // ส่งข้อมูลทุก 30 วินาที
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("\n=== 🌧️ เริ่มต้นระบบตรวจจับฝน ===");
// ตั้งค่า Servo
windowServo.attach(SERVO_PIN);
windowServo.write(SERVO_OPEN_ANGLE); // เริ่มต้นด้วยการเปิดหน้าต่าง
Serial.println("✅ Servo Motor เริ่มทำงานแล้ว");
// ตั้งค่า Rain Sensor (ESP32 ไม่ต้อง pinMode สำหรับ analog input)
Serial.println("✅ Rain Sensor พร้อมใช้งาน");
// เชื่อมต่อ WiFi
connectToWiFi();
Serial.println("✅ เริ่มทำงานเรียบร้อย รอตรวจจับฝน...\n");
}
void loop() {
unsigned long currentTime = millis();
// ตรวจสอบฝนทุก 2 วินาที
if (currentTime - lastCheckTime >= CHECK_INTERVAL) {
lastCheckTime = currentTime;
checkRainSensor();
}
// ส่งข้อมูลไป CynoIoT ทุก 30 วินาที
if (currentTime - lastSendTime >= SEND_INTERVAL) {
lastSendTime = currentTime;
sendToCynoIoT();
}
}
// ================== ฟังก์ชันตรวจสอบ Rain Sensor ==================
void checkRainSensor() {
int rainValue = analogRead(RAIN_SENSOR_PIN);
Serial.print("🌧️ ค่า Rain Sensor: ");
Serial.print(rainValue);
Serial.print(" | Threshold: ");
Serial.print(RAIN_THRESHOLD);
// ตรวจสอบว่ามีฝนหรือไม่
// *** สำคัญ: เซนเซอร์บางตัวให้ค่าสูงเมื่อแห้ง และต่ำเมื่อเปียก ***
// ถ้าเซนเซอร์ของคุณทำงานตรงกันข้าม ให้เปลี่ยนเครื่องหมาย > เป็น <
bool raining = (rainValue > RAIN_THRESHOLD);
if (raining && !isRaining) {
// เริ่มฝนตก
isRaining = true;
Serial.println(" -> ⛈️ ตรวจพบฝน! กำลังปิดหน้าต่าง...");
closeWindow();
} else if (!raining && isRaining) {
// ฝนหยุดตก
isRaining = false;
Serial.println(" -> ☀️ ฝนหยุดตก หน้าต่างยังคงปิดอยู่");
// ถ้าต้องการให้เปิดหน้าต่างอัตโนมัติเมื่อฝนหยุด ให้เปิด comment บรรทัดถัดไป
// openWindow();
} else {
Serial.println();
}
}
// ================== ฟังก์ชันปิดหน้าต่าง ==================
void closeWindow() {
Serial.println("🔒 กำลังปิดหน้าต่าง...");
windowServo.write(SERVO_CLOSE_ANGLE);
windowIsClosed = true;
delay(1000);
Serial.println("✅ ปิดหน้าต่างเรียบร้อย!");
}
// ================== ฟังก์ชันเปิดหน้าต่าง ==================
void openWindow() {
Serial.println("🔓 กำลังเปิดหน้าต่าง...");
windowServo.write(SERVO_OPEN_ANGLE);
windowIsClosed = false;
delay(1000);
Serial.println("✅ เปิดหน้าต่างเรียบร้อย!");
}
// ================== ฟังก์ชันเชื่อมต่อ WiFi ==================
void connectToWiFi() {
Serial.print("📡 เชื่อมต่อ WiFi: ");
Serial.println(ssid);
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 สำเร็จ!");
Serial.print("📌 IP Address: ");
Serial.println(WiFi.localIP());
} else {
Serial.println("\n❌ ไม่สามารถเชื่อมต่อ WiFi ได้");
Serial.println("⚠️ ระบบจะทำงานในโหมด offline (ไม่ส่งข้อมูลไป CynoIoT)");
}
}
// ================== ฟังก์ชันส่งข้อมูลไป CynoIoT ==================
void sendToCynoIoT() {
if (WiFi.status() != WL_CONNECTED) {
Serial.println("⚠️ WiFi ไม่ได้เชื่อมต่อ ข้ามการส่งข้อมูล");
return;
}
HTTPClient http;
String url = String("http://") + cynoiotServer + "/api/devices/data";
http.begin(url);
http.addHeader("Content-Type", "application/json");
http.addHeader("X-API-Key", deviceApiKey);
// สร้าง JSON payload
String payload = "{\"raining\":" + String(isRaining ? "true" : "false") +
",\"window_closed\":" + String(windowIsClosed ? "true" : "false") +
",\"rain_value\":" + String(analogRead(RAIN_SENSOR_PIN)) +
"}";
int httpResponseCode = http.POST(payload);
if (httpResponseCode > 0) {
Serial.print("📤 ส่งข้อมูลไป CynoIoT: ");
Serial.println(httpResponseCode);
} else {
Serial.print("❌ ส่งข้อมูลไม่สำเร็จ: ");
Serial.println(http.errorToString(httpResponseCode));
}
http.end();
}3. การอัปโหลดโค้ด
- เชื่อมต่อ ESP32 เข้ากับคอมพิวเตอร์ด้วยสาย USB
- เลือกบอร์ด:
Tools → Board → ESP32 Arduino → ESP32 Dev Module - เลือก Port:
Tools → Port → (เลือกพอร์ตที่ ESP32 เชื่อมต่อ) - กด
Uploadหรือกด Ctrl+U - รอจนกว่าจะขึ้น "Done uploading"
- เปิด Serial Monitor (Ctrl+Shift+M) เพื่อดูผลลัพธ์
⚙️ การปรับแต่งค่า Threshold
Rain Sensor แต่ละรุ่นอาจให้ค่าที่ต่างกัน:
- • แบบทั่วไป: ค่าต่ำ (~500-1000) = แห้ง, ค่าสูง (~3000+) = ฝน
- • บางรุ่น: ค่าสูง = แห้ง, ค่าต่ำ = ฝน (ตรงกันข้าม)
- • วิธีทดสอบ: เปิด Serial Monitor แล้วหยดน้ำลงบนเซนเซอร์ ดูว่าค่าเปลี่ยนอย่างไร
🌐 การเชื่อมต่อ CynoIoT Platform
CynoIoT Platform ช่วยให้คุณตรวจสอบสถานะระบบจากระยะไกล รับแจ้งเตือน และบันทึกข้อมูลประวัติการตรวจจับฝน
ขั้นตอนการเชื่อมต่อ
- สมัครบัญชี CynoIoT
ไปที่ cynoiot.com และสมัครบัญชีฟรี
- สร้างอุปกรณ์ใหม่
ไปที่ Dashboard → Devices → Add New Device
- รับ API Key
คัดลอก Device API Key มาใส่ในโค้ดบรรทัด
deviceApiKey - ตั้งค่า Data Fields
สร้างฟิลด์ข้อมูล:
raining,window_closed,rain_value - ตั้งค่าการแจ้งเตือน
สร้าง Notification Rule: เมื่อ
raining == trueให้แจ้งเตือน
✨ ประโยชน์ของ CynoIoT Integration
- • 📊 ดูกราฟประวัติการตรวจจับฝนย้อนหลัง
- • 🔔 รับแจ้งเตือนทันทีเมื่อตรวจพบฝน
- • 📱 เปิดดูสถานะหน้าต่างจากมือถือได้ทุกที่
- • 🤖 เชื่อมต่อกับระบบอัตโนมัติอื่นๆ ได้
- • 📈 วิเคราะห์ข้อมูลฝนในพื้นที่ของคุณ
🧪 การทดสอบระบบ
1. ทดสอบ Rain Sensor
- เปิด Serial Monitor (115200 baud)
- ดูค่า Rain Sensor ปัจจุบัน
- หยดน้ำหรือเปียกเซนเซอร์ด้วยผ้าชุบน้ำ
- สังเกตว่าค่าเปลี่ยนไปอย่างไร
- ปรับค่า
RAIN_THRESHOLDถ้าจำเป็น
ตัวอย่าง Serial Output:🌧️ ค่า Rain Sensor: 3500 | Threshold: 2000 -> ⛈️ ตรวจพบฝน! กำลังปิดหน้าต่าง...
2. ทดสอบ Servo Motor
- ตรวจสอบว่า Servo หมุนไปที่มุม
SERVO_OPEN_ANGLEเมื่อเริ่มต้น - หยดน้ำลงบน Rain Sensor
- Servo ควรจะหมุนไปที่
SERVO_CLOSE_ANGLE - เช็ค Serial Monitor ว่าขึ้น "ปิดหน้าต่างเรียบร้อย!"
- ล้างน้ำออกจากเซนเซอร์แล้วดูว่ามีอะไรเกิดขึ้น (ควรจะไม่เปิดหน้าต่างถ้ายังฝนตก)
3. ทดสอบ CynoIoT Connection
- ตรวจสอบว่าเชื่อมต่อ WiFi แล้ว (ดู IP Address ใน Serial Monitor)
- รอสักครู่ (30 วินาที) ให้ ESP32 ส่งข้อมูลไป CynoIoT
- เปิด CynoIoT Dashboard
- ดูว่ามีข้อมูลใหม่เข้ามาหรือไม่
- ตรวจสอบฟิลด์:
raining,window_closed,rain_value
💡 เคล็ดลับการทดสอบ
- • ใช้ปืนยิงละอองน้ำ (Spray Bottle) จำลองฝนได้ดีกว่าการหยดน้ำ
- • ปรับมุมเซนเซอร์ให้เอียงเล็กน้อย เพื่อให้น้ำไหลออกได้ดี
- • ติดตั้งเซนเซอร์ในที่โล่งจากลมแรง
- • ทดสอบระยะไกลด้วยการเปิด-ปิดน้ำในบ้าน แล้วดู CynoIoT
🔧 ปัญหาที่พบบ่อยและวิธีแก้ไข
❌ ปัญหา: Rain Sensor ให้ค่าผิดปกติ
อาการ: เซนเซอร์ตรวจพบฝนตลอดเวลา หรือไม่ตรวจพบเลย
สาเหตุ: Threshold ผิด, เซนเซอร์สกปรก, หรือต่อวงจรผิด
วิธีแก้:
- ปรับค่า
RAIN_THRESHOLDให้เหมาะสม - ล้างเซนเซอร์ด้วยผ้าแห้ง
- ตรวจสอบว่าเซนเซอร์ของคุณให้ค่าตรงกันข้ามหรือไม่ (ใช้ Serial Monitor ดู)
❌ ปัญหา: Servo ไม่หมุน
อาการ: หน้าต่างไม่เปิด/ปิด
สาเหตุ: ไฟไม่พอ, ต่อสายผิด, หรือ Servo เสีย
วิธีแก้:
- ใช้แหล่งจ่ายไฟภายนอก 5V 2A สำหรับ MG996R
- ตรวจสอบการต่อสาย Signal, VCC, GND
- ลองทดสอบ Servo ด้วย Sweep Example ใน Arduino IDE
❌ ปัญหา: WiFi เชื่อมต่อไม่ได้
อาการ: ขึ้น "ไม่สามารถเชื่อมต่อ WiFi ได้"
สาเหตุ: รหัสผ่านผิด, WiFi 5GHz, หรือสัญญาณอ่อน
วิธีแก้:
- ตรวจสอบว่าใช้ WiFi 2.4GHz (ESP32 ไม่รองรับ 5GHz)
- ตรวจสอบชื่อและรหัส WiFi
- ลองใช้มือถือ Hotspot เพื่อทดสอบ
❌ ปัญหา: ส่งข้อมูลไป CynoIoT ไม่ได้
อาการ: ขึ้น "ส่งข้อมูลไม่สำเร็จ"
สาเหตุ: API Key ผิด, Server down, หรือ WiFi ไม่ได้เชื่อมต่อ
วิธีแก้:
- ตรวจสอบ Device API Key ใน CynoIoT Dashboard
- ตรวจสอบว่า Server URL ถูกต้อง
- ดู Serial Monitor สำหรับ Error Code เพิ่มเติม
❌ ปัญหา: หน้าต่างเปิด/ปิดเองโดยไม่มีฝน
อาการ: Servo หมุนเมื่อไม่มีฝน
สาเหตุ: ความชื้นสูง, หมอก, หรือ Threshold ไวเกินไป
วิธีแก้:
- ปรับค่า Threshold ให้เหมาะสมกับสภาพแวดล้อม
- ติดตั้งเซนเซอร์ในที่ที่ไม่โดนหมอก/ควัน
- เพิ่มการ debounce (ให้ค่าอยู่เหนือ/ต่ำ threshold นาน 5 วินาทีก่อน trigger)
🎯 สรุป
ยินดีด้วย! คุณได้สร้างระบบตรวจจับฝนและปิดหน้าต่างอัตโนมัติสำเร็จแล้ว 🎉 โปรเจกต์นี้แสดงให้เห็นว่า IoT สามารถช่วยแก้ปัญหาในชีวิตจริงได้อย่างไร
✅ สิ่งที่เรียนรู้
- • การใช้งาน Rain Sensor
- • การควบคุม Servo Motor
- • การเชื่อมต่อ ESP32 กับ WiFi
- • การส่งข้อมูลไป Cloud Platform
- • การสร้างระบบ Automation แบบ End-to-End
🚀 ไอเดียต่อยอด
- • เพิ่มเซนเซอร์ตรวจจับความชื้น (DHT22)
- • ทำแผงควบคุมหลายหน้าต่างพร้อมกัน
- • เพิ่มระบบเปิดหน้าต่างอัตโนมัติเมื่ออากาศดี
- • เชื่อมต่อกับ Smart Home System (Google Home, Alexa)
- • ใช้ Solar Panel เพื่อประหยัดไฟ
🌧️ พร้อมรับมือฤดูฝนแล้วหรือยัง?
ฤดูฝนในไทยกำลังมาถึง ลองสร้างโปรเจกต์นี้เพื่อป้องกันน้ำฝนเข้าบ้านคุณ! และอย่าลืมแชร์ประสบการณ์ของคุณในคอมเมนต์ด้านล่างนะ 😉