📑 เนื้อหาในบทความ
🎯 ภาพรวมโปรเจกต์
ระบบวัดระดับน้ำอัจฉริยะเป็นโปรเจกต์ IoT ที่มีประโยชน์อย่างมากสำหรับชีวิตประจำวัน โดยเฉพาะในประเทศไทยที่เผชิญกับปัญหาน้ำท่วมและต้องการจัดการน้ำอย่างมีประสิทธิภาพ
ในบทความนี้คุณจะได้เรียนรู้:
- การใช้งานเซ็นเซอร์วัดระยะทาง Ultrasonic กับ ESP32
- การเขียนโปรแกรมวัดระดับน้ำและคำนวณปริมาณ
- การเชื่อมต่อกับ CynoIoT Platform เพื่อตรวจสอบข้อมูลระยะไกล
- การตั้งค่าการแจ้งเตือนเมื่อระดับน้ำสูงเกินไป
💡 เคล็ดลับ: โปรเจกต์นี้สามารถนำไปประยุกต์ใช้ได้หลากหลาย เช่น การตรวจสอบระดับน้ำในถังเก็บน้ำ, แทงค์น้ำ, บ่อบำบัดน้ำเสีย, หรือระบบเตือนภัยน้ำท่วม
🔧 อุปกรณ์ที่ต้องใช้
Hardware Components
ESP32 Board
ไมโครคอนโทรลเลอร์ที่มี WiFi และ Bluetooth
ราคา: ~฿150-300
HC-SR04 Ultrasonic Sensor
เซ็นเซอร์วัดระยะทาง (2cm - 400cm)
ราคา: ~฿30-50
Jumper Wires
สายเชื่อมต่อ (Male-to-Female)
ราคา: ~฿20-40
USB Cable & Power Supply
สาย USB สำหรับ ESP32
ราคา: ~฿30-50
Software & Tools
- ✓Arduino IDE - สำหรับเขียนและอัปโหลดโค้ด
- ✓CynoIoT Account - บัญชีฟรีสำหรับเชื่อมต่อ IoT
- ✓ESP32 Board Package - ติดตั้งผ่าน Arduino IDE
⚠️ หมายเหตุ: หากต้องการติดตั้งในที่กลางแจ้งแบบถาวร ควรใช้ JSN-SR04T (รุ่นกันน้ำ) แทน HC-SR04 และเพิ่ม Waterproof Box สำหรับ ESP32
🔌 การต่อวงจร
Pin Connections
| HC-SR04 Pin | ESP32 Pin | สายสี |
|---|---|---|
| VCC | 5V (or VIN) | แดง |
| Trig | GPIO 23 | ฟ้า/เหลือง |
| Echo | GPIO 22 | ฟ้า/เขียว |
| GND | GND | ดำ |
💡 เคล็ดลับ: หากใช้ JSN-SR04T รุ่นกันน้ำ การต่อขาจะเหมือนกันทุกประการ แต่ควรเพิ่มตัวต้านทาน 330Ω ต่ออนุกรัมกับขา Echo เพื่อป้องกันความเสียหายจากแรงดันไฟฟ้า
💻 โค้ดโปรแกรม
โค้ดวัดระดับน้ำ (Standalone Version)
// ตั้งค่าขา GPIO สำหรับ HC-SR04
const int trigPin = 23; // ขา Trigger
const int echoPin = 22; // ขา Echo
// ตั้งค่าถังน้ำ
const float tankDepth = 100.0; // ความลึกถังน้ำสูงสุด (cm)
const float tankRadius = 25.0; // รัศมีถังน้ำ (cm)
const float maxDistance = 200.0; // ระยะวัดสูงสุด (cm)
// ตัวแปรสำหรับคำนวณ
float duration, distance;
float waterLevel, waterVolume;
float percentage;
void setup() {
Serial.begin(115200); // เปิด Serial Monitor
// ตั้งค่าขา GPIO
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
// เริ่มต้นขา Trigger เป็น LOW
digitalWrite(trigPin, LOW);
Serial.println("ESP32 Water Level Monitor");
Serial.println("=========================");
delay(1000);
}
void loop() {
// ส่งสัญญาณ Ultrasonic
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// อ่านค่าจากขา Echo
duration = pulseIn(echoPin, HIGH);
// คำนวณระยะทาง (cm)
// ความเร็วเสียง = 343 m/s = 0.0343 cm/us
// ระยะทาง = (duration × 0.0343) / 2
distance = (duration * 0.0343) / 2;
// ตรวจสอบว่าค่าระยะอยู่ในช่วงที่ใช้งานได้
if (distance >= maxDistance || distance <= 0) {
Serial.println("⚠️ ไม่สามารถวัดระยะได้ (อยู่นอกช่วง)");
} else {
// คำนวณระดับน้ำ (ตำแหน่งผิวน้ำจากก้นถัง)
waterLevel = tankDepth - distance;
// ตรวจสอบว่าระดับน้ำไม่ติดลบ
if (waterLevel < 0) {
waterLevel = 0;
}
// คำนวณปริมาณน้ำ (ลิตร)
// ปริมาตรทรงกระบอก = π × r² × h
// แปลงจาก cm³ เป็น ลิตร (÷ 1000)
waterVolume = (3.14159 * tankRadius * tankRadius * waterLevel) / 1000.0;
// คำนวณเปอร์เซ็นต์
percentage = (waterLevel / tankDepth) * 100.0;
// แสดงผล
Serial.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
Serial.printf("ระยะทาง: %.2f cm\n", distance);
Serial.printf("ระดับน้ำ: %.2f cm (จากก้นถัง)\n", waterLevel);
Serial.printf("ปริมาณน้ำ: %.2f ลิตร\n", waterVolume);
Serial.printf("เปอร์เซ็นต์: %.1f%%\n", percentage);
// แจ้งเตือนเมื่อน้ำเกิน 80%
if (percentage >= 80.0) {
Serial.println("⚠️ ระดับน้ำสูงเกิน 80%!");
}
// แจ้งเตือนเมื่อน้ำต่ำกว่า 20%
else if (percentage <= 20.0) {
Serial.println("⚠️ ระดับน้ำต่ำกว่า 20%!");
}
Serial.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
}
delay(2000); // วัดทุก ๆ 2 วินาที
}📝 หมายเหตุ: อย่าลืมปรับค่า tankDepth (ความลึกถัง) และ tankRadius (รัศมีถัง) ให้ตรงกับขนาดถังน้ำของคุณ
🌐 เชื่อมต่อกับ CynoIoT Platform
1. สร้าง Device บน CynoIoT
- ล็อกอินเข้าสู่ CynoIoT Platform
- ไปที่ "Devices" → "Add New Device"
- ตั้งชื่อ Device (เช่น: "WaterLevelMonitor_Tank1")
- เลือก Device Type: "Custom"
- คัดลอก Device ID และ API Key
2. โค้ดเชื่อมต่อ CynoIoT (WiFi + MQTT)
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
// ตั้งค่า WiFi
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
// ตั้งค่า CynoIoT
const char* cynoiot_server = "api.cynoiot.com";
const String device_id = "YOUR_DEVICE_ID";
const String api_key = "YOUR_API_KEY";
// ตั้งค่าขา GPIO
const int trigPin = 23;
const int echoPin = 22;
// ตั้งค่าถังน้ำ
const float tankDepth = 100.0;
const float tankRadius = 25.0;
const float maxDistance = 200.0;
// ตัวแปร
float duration, distance;
float waterLevel, waterVolume;
float percentage;
unsigned long lastSendTime = 0;
const long sendInterval = 5000; // ส่งข้อมูลทุก ๆ 5 วินาที
void setup() {
Serial.begin(115200);
// ตั้งค่าขา GPIO
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
digitalWrite(trigPin, LOW);
// เชื่อมต่อ WiFi
WiFi.begin(ssid, password);
Serial.print("กำลังเชื่อมต่อ WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\n✅ เชื่อมต่อ WiFi สำเร็จ!");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
}
void loop() {
// วัดระดับน้ำ
measureWaterLevel();
// ส่งข้อมูลไป CynoIoT ทุก ๆ 5 วินาที
if (millis() - lastSendTime >= sendInterval) {
if (WiFi.status() == WL_CONNECTED) {
sendDataToCynoIoT();
lastSendTime = millis();
} else {
Serial.println("❌ WiFi ไม่ได้เชื่อมต่อ");
}
}
delay(100);
}
void measureWaterLevel() {
// ส่งสัญญาณ Ultrasonic
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration * 0.0343) / 2;
if (distance >= maxDistance || distance <= 0) {
waterLevel = 0;
waterVolume = 0;
percentage = 0;
} else {
waterLevel = tankDepth - distance;
if (waterLevel < 0) waterLevel = 0;
waterVolume = (3.14159 * tankRadius * tankRadius * waterLevel) / 1000.0;
percentage = (waterLevel / tankDepth) * 100.0;
}
}
void sendDataToCynoIoT() {
HTTPClient http;
// สร้าง JSON payload
DynamicJsonDocument doc(256);
doc["device_id"] = device_id;
doc["data"]["distance"] = round(distance * 10) / 10;
doc["data"]["water_level"] = round(waterLevel * 10) / 10;
doc["data"]["water_volume"] = round(waterVolume * 10) / 10;
doc["data"]["percentage"] = round(percentage * 10) / 10;
doc["timestamp"] = millis();
String payload;
serializeJson(doc, payload);
// ส่งข้อมูล
String url = String("https://") + cynoiot_server + "/api/v1/device/data";
http.begin(url);
http.addHeader("Content-Type", "application/json");
http.addHeader("X-API-Key", api_key);
int httpResponseCode = http.POST(payload);
if (httpResponseCode > 0) {
Serial.printf("✅ ส่งข้อมูลสำเร็จ (HTTP %d)\n", httpResponseCode);
Serial.printf(" ระดับน้ำ: %.1f%% (%.2f ลิตร)\n", percentage, waterVolume);
} else {
Serial.printf("❌ ส่งข้อมูลไม่สำเร็จ: %s\n", http.errorToString(httpResponseCode).c_str());
}
http.end();
}🚀 Next Level: หลังจากเชื่อมต่อสำเร็จ คุณสามารถตั้งค่า Alert Rules บน CynoIoT เพื่อให้แจ้งเตือนผ่าน Line, Telegram หรือ Email เมื่อระดับน้ำถึงเกณฑ์ที่กำหนด
✅ การทดสอบระบบ
ขั้นตอนการทดสอบ
- ตรวจสอบการต่อวงจร
ตรวจสอบให้แน่ใจว่าสายเชื่อมต่อทุกขาถูกต้อง และไม่มีขาหลวม
- อัปโหลดโค้ด
เปิด Serial Monitor ( baud rate 115200) เพื่อดูข้อความตอบรับ
- ทดสอบเซ็นเซอร์
ใช้มือหรือวัสดุบล็อกระหว่างเซ็นเซอร์ แล้วดูค่าระยะทางที่แสดงใน Serial Monitor
- ทดสอบในถังน้ำจริง
ติดตั้งเซ็นเซอร์ด้านบนถังน้ำ เทน้ำลงไปและดูค่าที่วัดได้
- ทดสอบ CynoIoT Connection
ตรวจสอบว่าข้อมูลถูกส่งไปยัง Dashboard ของ CynoIoT
ผลลัพธ์ที่คาดหวัง
ESP32 Water Level Monitor ========================= ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ระยะทาง: 45.32 cm ระดับน้ำ: 54.68 cm (จากก้นถัง) ปริมาณน้ำ: 107.25 ลิตร เปอร์เซ็นต์: 54.7% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ ส่งข้อมูลสำเร็จ (HTTP 200) ระดับน้ำ: 54.7% (107.2 ลิตร)
🔧 การแก้ปัญหาที่พบบ่อย
❓ เซ็นเซอร์แสดงค่า 0 หรือค่าผิดปกติ
อาการ: แสดงค่า 0 cm หรือค่าที่ไม่เปลี่ยนแปลง
สาเหตุ: การต่อวงจรไม่ถูกต้อง, เซ็นเซอร์เสีย, หรือระยะไกลเกินไป
วิธีแก้: ตรวจสอบการต่อขา VCC, GND, Trig, Echo ให้ถูกต้อง ลองเปลี่ยนเซ็นเซอร์ตัวใหม่
❓ ค่าระดับน้ำไม่แม่นยำ
อาการ: ค่าที่วัดได้ต่างจากความจริงมาก
สาเหตุ: ความลึกถังไม่ตรง, รัศมีถังผิด, หรือเซ็นเซอร์วางไม่ตั้งฉาก
วิธีแก้: ปรับค่า tankDepth และ tankRadius ให้ตรงกับถังจริง วางเซ็นเซอร์ให้ตั้งฉากกับผิวน้ำ
❓ เชื่อมต่อ WiFi ไม่ได้
อาการ: แสดง "WiFi ไม่ได้เชื่อมต่อ"
สาเหตุ: ชื่อ WiFi/Password ผิด, สัญญาณอ่อน, หรือ ESP32 อยู่ไกลเกินไป
วิธีแก้: ตรวจสอบ SSID และ Password ย้าย ESP32 ไปใกล้ Access Point หรือใช้ External Antenna
❓ ส่งข้อมูลไป CynoIoT ไม่ได้
อาการ: แสดง "ส่งข้อมูลไม่สำเร็จ: HTTP -1"
สาเหตุ: Device ID หรือ API Key ผิด, ไม่มี Internet, หรือ Server ล่ม
วิธีแก้: ตรวจสอบ Device ID และ API Key ให้ถูกต้อง ตรวจสอบ Internet Connection ลอง Ping ไปที่ api.cynoiot.com
🎉 สรุป
ในบทความนี้คุณได้เรียนรู้วิธีสร้างระบบวัดระดับน้ำอัจฉริยะด้วย ESP32 และ CynoIoT ตั้งแต่การต่อวงจร, เขียนโค้ด, ไปจนถึงการเชื่อมต่อ IoT Cloud เพื่อตรวจสอบข้อมูลระยะไกล
สิ่งที่คุณสามารถทำต่อได้:
- ปรับปรุงระบบ: เพิ่มจอ LCD แสดงผล, เพิ่ม Buzzer แจ้งเตือน
- ขยายระบบ: เพิ่มเซ็นเซอร์หลายจุด, ติดตั้งหลายถัง
- อัปเกรดเซ็นเซอร์: ใช้ JSN-SR04T กันน้ำสำหรับติดตั้งภายนอก
- เพิ่มฟีเจอร์: ใช้ Deep Sleep ประหยัดแบตเตอรี่, เพิ่ม Solar Panel
🚀 ถัดไป: โปรเจกต์ที่เกี่ยวข้อง