ทำระบบเฝ้าสังเกตพืชอัจฉริยะด้วย ESP32 - วัดความชื้นดิน อุณหภูมิ และความชื้นอากาศ

สร้างระบบเฝ้าสังเกตพืชอัตโนมัติที่บอกได้ว่าพืของคุณต้องการน้ำเมื่อไหร่ พร้อมแจ้งเตือนทาง LINE เพื่อไม่ให้พืชตาย

📅 23 มีนาคม 2026⏱️ 20 นาที🎯 ระดับเริ่มต้น

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

ทุกปัญหาของคนรักพืชคือ "รดน้ำมากไปหรือน้อยไป" ระบบเฝ้าสังเกตพืชอัจฉริยะ (Smart Plant Monitoring System) จะช่วยแก้ปัญหานี้ด้วย:

  • วัดความชื้นในดิน - รู้ได้ทันทีว่าพืชต้องการน้ำ
  • วัดอุณหภูมิและความชื้นอากาศ - เพื่อสภาพแวดล้อมที่เหมาะสม
  • แจ้งเตือนอัตโนมัติ - ผ่าน LINE Notification เมื่อดินแห้ง
  • บันทึกข้อมูล - ดูประวัติการเปลี่ยนแปลงได้ที่ CynoIoT Platform
  • ประหยัดเงิน - เมื่อเทียบกับซื้อของสำเร็จรูป (฿500-800 บาท ในตลาด)

💡 ทำไมต้องทำเอง? ระบบทำเองปรับแต่งได้ตามต้องการ เพิ่มเซ็นเซอร์อื่นๆ ได้ และเรียนรู้การทำงานของ IoT จริงๆ นอกจากนี้ยังเชื่อมต่อกับ CynoIoT Platform ได้ฟรี!

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

Hardware

อุปกรณ์จำนวนราคาโดยประมาณ
ESP32 DevKit / NodeMCU ESP321฿80-150
Soil Moisture Sensor ( capacitive )1฿30-50
DHT22 / AM2302 (Temp & Humidity)1฿40-60
Jumper Wires (female-to-female)-฿20-30
Breadboard หรือ PCB1฿15-30
USB Cable สำหรับ ESP321฿15-25

Software

  • Arduino IDE - สำหรับอัปโหลดโค้ด
  • Library: DHT sensor library by Adafruit
  • Library: WiFi Client & HTTPS (สำหรับ LINE Notify)
  • Library: CynoIoT MQTT Client (ถ้าใช้ CynoIoT)

💡 เคล็ดลับ: ให้ใช้ Capacitive Soil Moisture Sensor แทน Resistive Sensor เพราะทนทานกว่าและไม่เกิดการกัดกร่อน (corrosion) ราคาใกล้เคียงกันแต่อายุการใช้งานยาวนานกว่ามาก

การต่อวงจร

การต่อวงจรทำได้ง่ายมาก เพราะใช้เซ็นเซอร์แบบดิจิทัลทั้งหมด ไม่ต้องกังวลเรื่องค่า analog

ต่อ Soil Moisture Sensor (Capacitive)

Soil Moisture Sensor → ESP32
VCC → 3.3V
GND → GND
OUT (Signal) → GPIO 34 (ADC1_CH6)

ต่อ DHT22 Sensor

DHT22 → ESP32
VCC (Pin 1) → 3.3V
DATA (Pin 2) → GPIO 4
GND (Pin 4) → GND

ต่อตัวต้านทาน 10kΩ ระหว่าง VCC และ DATA (pull-up)

⚠️ ข้อควรระวัง: GPIO 34-39 บน ESP32 เป็น input only ไม่สามารถใช้เป็น output ได้ ให้ใช้เฉพาะสำหรับอ่านค่าจากเซ็นเซอร์เท่านั้น

การเขียนโปรแกรม

โค้ดต่อไปนี้จะอ่านค่าจากเซ็นเซอร์ทั้งสองและส่งข้อมูลไปยัง CynoIoT Platform พร้อมแจ้งเตือนผ่าน LINE เมื่อดินแห้งเกินไป

plant_monitor.ino
#include <WiFi.h>
#include <HTTPClient.h>
#include <DHT.h>
#include <PubSubClient.h>

// ===== ตั้งค่า WiFi =====
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";

// ===== ตั้งค่า LINE Notify =====
const char* lineToken = "YOUR_LINE_NOTIFY_TOKEN";

// ===== ตั้งค่า CynoIoT MQTT =====
const char* mqttServer = "mqtt.cynoiot.com";
const int mqttPort = 1883;
const char* mqttUser = "YOUR_CYNOIOT_TOKEN";
const char* mqttPass = "";
const char* deviceId = "plant-monitor-001";

// ===== ตั้งค่าเซ็นเซอร์ =====
#define SOIL_PIN 34        // GPIO สำหรับ Soil Moisture
#define DHT_PIN 4          // GPIO สำหรับ DHT22
#define DHT_TYPE DHT22

DHT dht(DHT_PIN, DHT_TYPE);

WiFiClient espClient;
PubSubClient mqttClient(espClient);

// ตัวแปรสำหรับเก็บค่าเก่า
float lastSoilMoisture = 100;
bool notified = false;

void setup() {
  Serial.begin(115200);
  
  // เริ่มต้นเซ็นเซอร์
  dht.begin();
  
  // เริ่มต้น WiFi
  WiFi.begin(ssid, password);
  Serial.print("กำลังเชื่อมต่อ WiFi");
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  
  Serial.println("\nWiFi เชื่อมต่อแล้ว!");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  
  // ตั้งค่า MQTT
  mqttClient.setServer(mqttServer, mqttPort);
  
  delay(2000);
}

void loop() {
  // ตรวจสอบการเชื่อมต่อ MQTT
  if (!mqttClient.connected()) {
    reconnectMQTT();
  }
  mqttClient.loop();
  
  // อ่านค่าจากเซ็นเซอร์
  float soilMoisture = readSoilMoisture();
  float temperature = dht.readTemperature();
  float humidity = dht.readHumidity();
  
  // ตรวจสอบว่าอ่านค่าสำเร็จหรือไม่
  if (isnan(temperature) || isnan(humidity)) {
    Serial.println("ไม่สามารถอ่านค่าจาก DHT22 ได้!");
    delay(2000);
    return;
  }
  
  // แสดงค่าบน Serial Monitor
  Serial.println("===== ข้อมูลเซ็นเซอร์ =====");
  Serial.printf("ความชื้นในดิน: %.1f%%\n", soilMoisture);
  Serial.printf("อุณหภูมิ: %.1f°C\n", temperature);
  Serial.printf("ความชื้นอากาศ: %.1f%%\n", humidity);
  Serial.println("=====================");
  
  // ส่งข้อมูลไปยัง CynoIoT
  sendToCynoIoT(soilMoisture, temperature, humidity);
  
  // แจ้งเตือนผ่าน LINE ถ้าดินแห้งเกิน 30%
  if (soilMoisture < 30 && !notified) {
    sendLineAlert(soilMoisture, temperature, humidity);
    notified = true;
  }
  
  // รีเซ็ตการแจ้งเตือนเมื่อดินชื้นกลับมา
  if (soilMoisture > 50) {
    notified = false;
  }
  
  delay(60000); // อ่านทุกๆ 1 นาที
}

// ฟังก์ชันอ่านค่าความชื้นในดิน
float readSoilMoisture() {
  int rawValue = analogRead(SOIL_PIN);
  // แปลงค่า ADC (0-4095) เป็นเปอร์เซ็นต์
  // Capacitive sensor: แห้ง = ค่าต่ำ, ชื้น = ค่าสูง
  float moisture = map(rawValue, 0, 4095, 0, 100);
  return moisture;
}

// ฟังก์ชันส่งข้อมูลไปยัง CynoIoT
void sendToCynoIoT(float soil, float temp, float hum) {
  String payload = "{";
  payload += "\"soil_moisture\":" + String(soil) + ",";
  payload += "\"temperature\":" + String(temp) + ",";
  payload += "\"humidity\":" + String(hum);
  payload += "}";
  
  char topic[100];
  sprintf(topic, "device/%s/data", deviceId);
  
  mqttClient.publish(topic, payload.c_str());
  Serial.println("ส่งข้อมูลไปยัง CynoIoT แล้ว");
}

// ฟังก์ชันแจ้งเตือนผ่าน LINE
void sendLineAlert(float soil, float temp, float hum) {
  HTTPClient http;
  
  String message = "\\n⚠️ แจ้งเตือน: ดินของพืขแห้งแล้ว!\\n";
  message += String("━━━━━━━━━━━━━━━\\n");
  message += String("🌱 ความชื้นในดิน: ") + soil + "%\\n";
  message += String("🌡️ อุณหภูมิ: ") + temp + "°C\\n";
  message += String("💧 ความชื้นอากาศ: ") + hum + "%\\n";
  message += String("━━━━━━━━━━━━━━━\\n");
  message += String("⏰ เวลา: ") + getTimeString();
  
  http.begin("https://notify-api.line.me/api/notify");
  http.addHeader("Content-Type", "application/x-www-form-urlencoded");
  http.addHeader("Authorization", "Bearer " + String(lineToken));
  
  String httpRequestData = "message=" + message;
  int httpResponseCode = http.POST(httpRequestData);
  
  if (httpResponseCode > 0) {
    Serial.println("ส่งการแจ้งเตือน LINE สำเร็จ!");
  } else {
    Serial.print("Error ส่ง LINE: ");
    Serial.println(httpResponseCode);
  }
  
  http.end();
}

// ฟังก์ชันเชื่อมต่อ MQTT ใหม่
void reconnectMQTT() {
  while (!mqttClient.connected()) {
    Serial.print("กำลังเชื่อมต่อ MQTT...");
    
    if (mqttClient.connect(deviceId, mqttUser, mqttPass)) {
      Serial.println("เชื่อมต่อสำเร็จ!");
    } else {
      Serial.print("ล้มเหลว, rc=");
      Serial.print(mqttClient.state());
      Serial.println(" ลองใหม่ใน 5 วินาที");
      delay(5000);
    }
  }
}

// ฟังก์ชันเวลา (simple version)
String getTimeString() {
  return "เมื่อสักครู่นี้";
}

คำอธิบายโค้ด

  • setup() - เชื่อมต่อ WiFi และเริ่มต้นเซ็นเซอร์
  • loop() - อ่านค่าเซ็นเซอร์ทุกๆ 1 นาที
  • readSoilMoisture() - แปลงค่า ADC เป็นเปอร์เซ็นต์
  • sendToCynoIoT() - ส่งข้อมูลไปยัง Platform
  • sendLineAlert() - แจ้งเตือนเมื่อดินแห้ง

💡 เคล็ดลับ: สามารถปรับค่า threshold (เดิม: 30%) ตามชนิดของพืช เช่น กระบองเพชรต้องการน้ำน้อยกว่าเฟิร์น

เชื่อมต่อกับ CynoIoT Platform

CynoIoT เป็น Platform ฟรีสำหรับบริหารจัดการอุปกรณ์ IoT พร้อม Dashboard สวยงามและการแจ้งเตือน

ขั้นตอนการลงทะเบียน

  1. ไปที่ cynoiot.com และสมัครสมาชิกฟรี
  2. สร้าง Device ใหม่ ในระบบ (ได้รับ Device Token)
  3. นำ Token มาใส่ในโค้ดตรง mqttUser
  4. อัปโหลดโค้ดไปยัง ESP32
  5. ดูข้อมูลบน Dashboard ได้ทันที!

✅ ข้อดีของ CynoIoT: ฟรีไม่จำกัด Device, Dashboard สวยงาม, รองรับ MQTT, และมี API สำหรับเชื่อมต่อกับระบบอื่นๆ

การแก้ปัญหาที่พบบ่อย

ปัญหา: อ่านค่า DHT22 ไม่ได้

สาเหตุ: ต่อสายผิด, ไม่มีตัวต้านทาน pull-up, หรือ GPIO ผิด

วิธีแก้: ตรวจสอบการต่อสายให้ถูกต้อง ใส่ตัวต้านทาน 10kΩ ระหว่าง VCC และ DATA

ปัญหา: ค่า Soil Moisture ผิดปกติ

สาเหตุ: ใช้ resistive sensor (กัดกร่อน), ต่อขาผิด

วิธีแก้: เปลี่ยนเป็น capacitive sensor หรือทำ calibration ใหม่

ปัญหา: ส่ง LINE Notify ไม่ได้

สาเหตุ: Token ผิด, ข้อความยาวเกินไป, หรือไม่ได้ต่อ internet

วิธีแก้: ตรวจสอบ Token ให้ถูกต้อง, ลดความยาวข้อความ, ตรวจสอบการเชื่อมต่อ WiFi

ปัญหา: MQTT เชื่อมต่อไม่ได้

สาเหตุ: Device Token ผิด, ไม่ได้เชื่อมต่อ internet

วิธีแก้: ตรวจสอบ Device Token จาก CynoIoT Dashboard, ทดสอบ WiFi connection

สรุปสิ่งที่เรียนรู้

  • การต่อและใช้งาน Soil Moisture Sensor (Capacitive)
  • การอ่านค่า DHT22 สำหรับวัดอุณหภูมิและความชื้น
  • การส่งข้อมูลไปยัง CynoIoT Platform ผ่าน MQTT
  • การแจ้งเตือนผ่าน LINE Notify
  • การสร้างระบบ IoT ที่ใช้งานได้จริง

🎯 ถัดไป: ลองเพิ่มฟีเจอร์อื่นๆ เช่น ปั๊มน้ำอัตโนมัติ, จอแสดงผล, หรือเชื่อมต่อ Home Assistant

© 2026 CynoIoT. All rights reserved.