"""
วงจรตรวจวัดระดับน้ำ (Water Level Monitoring) ด้วย ESP32 + HC-SR04
ทดสอบบน Wokwi Simulator (MicroPython)
การต่อขา:
HC-SR04:
VCC -> 5V
GND -> GND
TRIG -> GPIO5
ECHO -> ผ่าน voltage divider (1k/2k) -> GPIO18
LED (แจ้งเตือนน้ำสูง):
Anode -> R220 -> GPIO2
Cathode-> GND
Buzzer (ไม่บังคับ):
+ -> GPIO4
- -> GND
"""
from machine import Pin, time_pulse_us
import time
# ---------- ตั้งค่าขา ----------
TRIG_PIN = 5
ECHO_PIN = 18
LED_PIN = 2
BUZZER_PIN = 4
trig = Pin(TRIG_PIN, Pin.OUT)
echo = Pin(ECHO_PIN, Pin.IN)
led = Pin(LED_PIN, Pin.OUT)
buzzer = Pin(BUZZER_PIN, Pin.OUT)
# ---------- ค่าคงที่ของถัง/ภาชนะ (ปรับตามจริง) ----------
TANK_HEIGHT_CM = 20.0 # ความสูงถังทั้งหมด (ระยะจากเซ็นเซอร์ถึงก้นถัง)
SENSOR_OFFSET_CM = 2.0 # ระยะจากปากเซ็นเซอร์ถึงระดับน้ำเต็ม
WARNING_LEVEL_PERCENT = 80 # เตือนเมื่อระดับน้ำเกิน 80%
led.value(0)
buzzer.value(0)
def measure_distance_cm():
"""ยิงสัญญาณอัลตราโซนิกแล้วคำนวณระยะทาง (เซนติเมตร)"""
trig.value(0)
time.sleep_us(2)
trig.value(1)
time.sleep_us(10)
trig.value(0)
# รอสัญญาณ echo กลับมา (timeout 30ms ป้องกันค้าง)
duration = time_pulse_us(echo, 1, 30000)
if duration < 0:
return None # วัดไม่สำเร็จ / นอกช่วง
# ความเร็วเสียง ~ 0.0343 cm/us หารสอง (ไป-กลับ)
distance = (duration * 0.0343) / 2
return distance
def distance_to_water_level(distance_cm):
"""แปลงระยะที่วัดได้ เป็น % ระดับน้ำในถัง"""
if distance_cm is None:
return None
water_height = TANK_HEIGHT_CM - (distance_cm - SENSOR_OFFSET_CM)
water_height = max(0, min(water_height, TANK_HEIGHT_CM))
percent = (water_height / TANK_HEIGHT_CM) * 100
return round(percent, 1)
def alert(is_high):
led.value(1 if is_high else 0)
buzzer.value(1 if is_high else 0)
print("=== เริ่มระบบตรวจวัดระดับน้ำ ===")
while True:
dist = measure_distance_cm()
if dist is None:
print("อ่านค่าเซ็นเซอร์ไม่สำเร็จ")
else:
level_percent = distance_to_water_level(dist)
print("ระยะที่วัดได้: {} cm | ระดับน้ำ: {}%".format(dist, level_percent))
if level_percent is not None and level_percent >= WARNING_LEVEL_PERCENT:
print(">>> เตือน! ระดับน้ำสูงเกิน {}% <<<".format(WARNING_LEVEL_PERCENT))
alert(True)
else:
alert(False)
time.sleep(1)