สร้างระบบตรวจจับฝนและปิดหน้าต่างอัตโนมัติด้วย ESP32 และ CynoIoT

เรียนรู้วิธีสร้างระบบ IoT ที่ตรวจจับฝนและปิดหน้าต่างอัตโนมัติเพื่อป้องกันน้ำฝนเข้าบ้าน พร้อมโค้ดตัวอย่างและการเชื่อมต่อ CynoIoT Platform

📅 16 มีนาคม 2026⏱️ 15 นาที🎯 ระดับผู้เริ่มต้น🌧️ เหมาะสำหรับฤดูฝน

🌧️ ภาพรวมโปรเจกต์

เคยเจอปัญหาน้ำฝนเข้าบ้านเพราะลืมปิดหน้าต่างไหม? ในฤดูฝนของไทย ฝนตกหนังหนังและมักจะตกในเวลาที่เราไม่อยู่บ้าน โปรเจกต์นี้จะช่วยแก้ปัญหานั้นด้วยการสร้างระบบตรวจจับฝนและปิดหน้าต่างอัตโนมัติเมื่อตรวจพบฝน

✨ จุดเด่นของโปรเจกต์

  • • ตรวจจับฝนแบบ Real-time ด้วย Rain Sensor
  • • ควบคุม Servo Motor ปิดหน้าต่างอัตโนมัติ
  • • เชื่อมต่อ WiFi และส่งข้อมูลไป CynoIoT Platform
  • • รับแจ้งเตือนผ่าน Application
  • • ตรวจสอบสถานะระยะไกลได้ทุกที่ทุกเวลา

หลักการทำงาน

  1. Rain Sensor ตรวจจับน้ำฝนบนพื้นผิว
  2. เมื่อตรวจพับฝน → ESP32 ส่งสัญญาณไป Servo Motor
  3. Servo Motor หมุนเพื่อปิดหน้าต่าง
  4. ESP32 ส่งข้อมูลไป CynoIoT Platform ผ่าน WiFi
  5. ผู้ใช้รับแจ้งเตือนและตรวจสอบสถานะผ่านแอป

🛠️ อุปกรณ์ที่ต้องใช้

🔌 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 DevKit1฿150
Rain Sensor Module1฿40
Servo Motor SG901฿50
Jumper Wires1 แพ็ค฿20
รวมทั้งหมด-฿260

🔗 การต่อวงจร

Rain Sensor Module → ESP32

Rain Sensor PinESP32 Pinหมายเหตุ
VCC3.3Vหรือ 5V ตาม Module
GNDGNDกราวด์
AO (Analog Out)GPIO 34สำหรับอ่านค่าแบบ analog
DO (Digital Out)GPIO 35สำหรับอ่านค่าแบบ digital (ใช้ไม่ได้กับบางบอร์ด)

⚠️ ข้อควรระวัง: GPIO 34-35 รองรับเฉพาะ Input เท่านั้น (Input-only) ห้ามใช้เป็น Output

Servo Motor → ESP32

Servo WireESP32 Pinสีสาย (มาตรฐาน)
SignalGPIO 18ส้ม/เหลือง
VCC5V (หรือ Vin)แดง
GNDGNDน้ำตาล/ดำ

💡 เคล็ดลับ: ถ้าใช้ 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. การอัปโหลดโค้ด

  1. เชื่อมต่อ ESP32 เข้ากับคอมพิวเตอร์ด้วยสาย USB
  2. เลือกบอร์ด: Tools → Board → ESP32 Arduino → ESP32 Dev Module
  3. เลือก Port: Tools → Port → (เลือกพอร์ตที่ ESP32 เชื่อมต่อ)
  4. กด Upload หรือกด Ctrl+U
  5. รอจนกว่าจะขึ้น "Done uploading"
  6. เปิด Serial Monitor (Ctrl+Shift+M) เพื่อดูผลลัพธ์

⚙️ การปรับแต่งค่า Threshold

Rain Sensor แต่ละรุ่นอาจให้ค่าที่ต่างกัน:

  • แบบทั่วไป: ค่าต่ำ (~500-1000) = แห้ง, ค่าสูง (~3000+) = ฝน
  • บางรุ่น: ค่าสูง = แห้ง, ค่าต่ำ = ฝน (ตรงกันข้าม)
  • วิธีทดสอบ: เปิด Serial Monitor แล้วหยดน้ำลงบนเซนเซอร์ ดูว่าค่าเปลี่ยนอย่างไร

🌐 การเชื่อมต่อ CynoIoT Platform

CynoIoT Platform ช่วยให้คุณตรวจสอบสถานะระบบจากระยะไกล รับแจ้งเตือน และบันทึกข้อมูลประวัติการตรวจจับฝน

ขั้นตอนการเชื่อมต่อ

  1. สมัครบัญชี CynoIoT

    ไปที่ cynoiot.com และสมัครบัญชีฟรี

  2. สร้างอุปกรณ์ใหม่

    ไปที่ Dashboard → Devices → Add New Device

  3. รับ API Key

    คัดลอก Device API Key มาใส่ในโค้ดบรรทัด deviceApiKey

  4. ตั้งค่า Data Fields

    สร้างฟิลด์ข้อมูล: raining, window_closed, rain_value

  5. ตั้งค่าการแจ้งเตือน

    สร้าง Notification Rule: เมื่อ raining == true ให้แจ้งเตือน

✨ ประโยชน์ของ CynoIoT Integration

  • • 📊 ดูกราฟประวัติการตรวจจับฝนย้อนหลัง
  • • 🔔 รับแจ้งเตือนทันทีเมื่อตรวจพบฝน
  • • 📱 เปิดดูสถานะหน้าต่างจากมือถือได้ทุกที่
  • • 🤖 เชื่อมต่อกับระบบอัตโนมัติอื่นๆ ได้
  • • 📈 วิเคราะห์ข้อมูลฝนในพื้นที่ของคุณ

🧪 การทดสอบระบบ

1. ทดสอบ Rain Sensor

  1. เปิด Serial Monitor (115200 baud)
  2. ดูค่า Rain Sensor ปัจจุบัน
  3. หยดน้ำหรือเปียกเซนเซอร์ด้วยผ้าชุบน้ำ
  4. สังเกตว่าค่าเปลี่ยนไปอย่างไร
  5. ปรับค่า RAIN_THRESHOLD ถ้าจำเป็น

ตัวอย่าง Serial Output:
🌧️ ค่า Rain Sensor: 3500 | Threshold: 2000 -> ⛈️ ตรวจพบฝน! กำลังปิดหน้าต่าง...

2. ทดสอบ Servo Motor

  1. ตรวจสอบว่า Servo หมุนไปที่มุม SERVO_OPEN_ANGLE เมื่อเริ่มต้น
  2. หยดน้ำลงบน Rain Sensor
  3. Servo ควรจะหมุนไปที่ SERVO_CLOSE_ANGLE
  4. เช็ค Serial Monitor ว่าขึ้น "ปิดหน้าต่างเรียบร้อย!"
  5. ล้างน้ำออกจากเซนเซอร์แล้วดูว่ามีอะไรเกิดขึ้น (ควรจะไม่เปิดหน้าต่างถ้ายังฝนตก)

3. ทดสอบ CynoIoT Connection

  1. ตรวจสอบว่าเชื่อมต่อ WiFi แล้ว (ดู IP Address ใน Serial Monitor)
  2. รอสักครู่ (30 วินาที) ให้ ESP32 ส่งข้อมูลไป CynoIoT
  3. เปิด CynoIoT Dashboard
  4. ดูว่ามีข้อมูลใหม่เข้ามาหรือไม่
  5. ตรวจสอบฟิลด์: 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 เพื่อประหยัดไฟ

🌧️ พร้อมรับมือฤดูฝนแล้วหรือยัง?

ฤดูฝนในไทยกำลังมาถึง ลองสร้างโปรเจกต์นี้เพื่อป้องกันน้ำฝนเข้าบ้านคุณ! และอย่าลืมแชร์ประสบการณ์ของคุณในคอมเมนต์ด้านล่างนะ 😉

📅 อัปเดตล่าสุด: 16 มีนาคม 2026👤 โดยทีมงาน CynoIoT