สร้างระบบวัดระดับน้ำอัจฉริยะด้วย ESP32 และ CynoIoT

เรียนรู้วิธีสร้างระบบวัดระดับน้ำอัตโนมัติที่สามารถเชื่อมต่อกับแพลตฟอร์ม CynoIoT เหมาะสำหรับการตรวจสอบระดับน้ำในถังเก็บน้ำ แทงค์น้ำ หรือเตือนภัยน้ำท่วม

📅 8 มีนาคม 2026⏱️ 15 นาที🎯 ระดับเริ่มต้น📊 ESP32, Ultrasonic Sensor

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

ระบบวัดระดับน้ำอัจฉริยะเป็นโปรเจกต์ 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 PinESP32 Pinสายสี
VCC5V (or VIN)แดง
TrigGPIO 23ฟ้า/เหลือง
EchoGPIO 22ฟ้า/เขียว
GNDGNDดำ

💡 เคล็ดลับ: หากใช้ 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

  1. ล็อกอินเข้าสู่ CynoIoT Platform
  2. ไปที่ "Devices" → "Add New Device"
  3. ตั้งชื่อ Device (เช่น: "WaterLevelMonitor_Tank1")
  4. เลือก Device Type: "Custom"
  5. คัดลอก 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 เมื่อระดับน้ำถึงเกณฑ์ที่กำหนด

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

ขั้นตอนการทดสอบ

  1. ตรวจสอบการต่อวงจร

    ตรวจสอบให้แน่ใจว่าสายเชื่อมต่อทุกขาถูกต้อง และไม่มีขาหลวม

  2. อัปโหลดโค้ด

    เปิด Serial Monitor ( baud rate 115200) เพื่อดูข้อความตอบรับ

  3. ทดสอบเซ็นเซอร์

    ใช้มือหรือวัสดุบล็อกระหว่างเซ็นเซอร์ แล้วดูค่าระยะทางที่แสดงใน Serial Monitor

  4. ทดสอบในถังน้ำจริง

    ติดตั้งเซ็นเซอร์ด้านบนถังน้ำ เทน้ำลงไปและดูค่าที่วัดได้

  5. ทดสอบ 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

© 2026 CynoIoT. All rights reserved.

สร้างด้วย ❤️ สำหรับชุมชน IoT ไทย