from machine import Pin, time_pulse_us
import time
# Pin definitions
TRIG_PIN = 19
ECHO_PIN = 18
BUZZER_PIN = 17
LED_PIN = 16
BUTTON_PIN = 15
# Initialize pins
trig = Pin(TRIG_PIN, Pin.OUT)
echo = Pin(ECHO_PIN, Pin.IN)
buzzer = Pin(BUZZER_PIN, Pin.OUT)
led = Pin(LED_PIN, Pin.OUT)
button = Pin(BUTTON_PIN, Pin.IN, Pin.PULL_UP)
def measure_distance():
trig.low()
time.sleep_us(2)
trig.high()
time.sleep_us(10)
trig.low()
duration = time_pulse_us(echo, 1, 30000)
if duration < 0: return None
return (duration * 0.0343) / 2
def main():
last_distance = None
unchanged_start_time = time.time()
last_sensor_read = 0
# SETTINGS
DISTANCE_THRESHOLD = 2.0 # Only jumps bigger than 2cm reset the timer
TIMEOUT_SECONDS = 10 # Alert after 10 seconds of "stillness"
alert_active = False
print("System Active. Monitoring for jumps > 2cm...")
while True:
current_time = time.time()
# 1. CHECK THE BUTTON CONSTANTLY (No delay here!)
if button.value() == 0:
print("!!! BUTTON RESET !!!")
buzzer.value(0)
led.value(0)
alert_active = False
last_distance = None
unchanged_start_time = time.time()
time.sleep(0.3) # Short debounce so it doesn't double-trigger
continue
# 2. ONLY MEASURE DISTANCE EVERY 1 SECOND
if current_time - last_sensor_read >= 1:
last_sensor_read = current_time
distance = measure_distance()
if distance is None:
print("Sensor error")
continue
if last_distance is None:
last_distance = distance
print(f"Initial Level: {distance:.2f} cm")
else:
diff = abs(distance - last_distance)
# Only reset if the jump is SIGNIFICANT (e.g., > 2cm)
if diff > DISTANCE_THRESHOLD:
unchanged_start_time = current_time
last_distance = distance # Update reference to the new level
print(f"Significant Change: {diff:.2f} cm. Timer Reset.")
else:
# Small ripples (< 2cm) are ignored, timer keeps ticking
elapsed = current_time - unchanged_start_time
print(f"Stable ({distance:.2f} cm) - Idle: {elapsed:.0f}s")
if elapsed >= TIMEOUT_SECONDS and not alert_active:
buzzer.value(1)
led.value(1)
alert_active = True
print("!!! STAGNANT WATER ALERT !!!")
# Small sleep so the CPU doesn't catch fire,
# but fast enough to catch every button press.
time.sleep(0.05)
if __name__ == "__main__":
main()