print("Program: Motion Sensor Alarm")
print("Date: 14/11/2024")
print("Created by: Afiq Ikmal")
from machine import Pin, I2C, PWM, SPI
import time
from hcsr04 import HCSR04
from lcd_api import LcdApi
from machine_i2c_lcd import I2cLcd
# Initialize components
# RGB LED
red = Pin(13, Pin.OUT)
green = Pin(12, Pin.OUT)
blue = Pin(14, Pin.OUT)
# Ultrasonic Sensor
ultrasonic = HCSR04(trigger_pin=5, echo_pin=18)
# PIR Sensor
pir = Pin(4, Pin.IN)
# Servo Motors
servo1 = PWM(Pin(23), freq=50) # Servo Motor 1
servo2 = PWM(Pin(27), freq=50) # Servo Motor 2
# LCD Display
i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=400000)
lcd = I2cLcd(i2c, 0x27, 2, 16)
# Push Button
push_button = Pin(2, Pin.IN, Pin.PULL_UP)
# Buzzer
buzzer = PWM(Pin(25))
# Helper function for RGB control
def rgb_color(r, g, b):
red.value(r)
green.value(g)
blue.value(b)
# Helper function for servo control
def set_servo_angle(servo, angle):
duty = int(40 + (angle / 180) * 115)
servo.duty(duty)
# Helper function for buzzer
def play_buzzer(frequency, duration):
buzzer.freq(frequency)
buzzer.duty(512) # 50% duty cycle for sound
time.sleep(duration)
buzzer.duty(0) # Turn off buzzer
# PIR Rain Detection: Blink Green LED and Play Buzzer
def rain_detected_alert():
for _ in range(3):
rgb_color(0, 1, 0) # Green LED ON
play_buzzer(1000, 0.2) # Short beep
time.sleep(0.2) # Pause
rgb_color(0, 0, 0) # Green LED OFF
time.sleep(0.2)
# Initialize system to standby
rgb_color(1, 0, 0) # Red LED ON (Standby)
# Wait for button press
while push_button.value():
time.sleep(0.1)
# Start system after button press
lcd.clear()
lcd.putstr("Starting System...")
rgb_color(0, 0, 0) # Turn off LED
time.sleep(2)
# Initial servo positions
set_servo_angle(servo1, 55) # Close Servo Motor 1
set_servo_angle(servo2, 55) # Close Servo Motor 2
lcd.clear()
lcd.putstr("Waiting for Rain")
while True:
# Check PIR Sensor for rain detection
if pir.value():
lcd.clear()
lcd.putstr("Rain Detected!")
rain_detected_alert() # Blink Green LED and sound buzzer
set_servo_angle(servo1, 130) # Open Servo Motor 1
time.sleep(2)
# Monitor water level with Ultrasonic Sensor
while True:
try:
distance = ultrasonic.distance_cm()
if distance < 0: # Handle invalid distance readings
distance = -1
except OSError:
distance = -1 # Error state
if 50 <= distance < 350: # Between 50 cm and 350 cm
lcd.clear()
lcd.putstr("Water Level:\n{} cm".format(distance))
time.sleep(1)
elif distance >= 350: # Reached 350 cm
lcd.clear()
lcd.putstr("Switching Valves")
set_servo_angle(servo1, 55) # Close Servo Motor 1
play_buzzer(1000, 0.2) # Short beep
time.sleep(2)
set_servo_angle(servo2, 130) # Open Servo Motor 2 (Drain valve)
play_buzzer(1000, 0.2) # Short beep
lcd.clear()
lcd.putstr("Draining Water")
# Monitor draining process
while True:
try:
drain_distance = ultrasonic.distance_cm()
if drain_distance < 0: # Handle invalid distance readings
drain_distance = -1
except OSError:
drain_distance = -1 # Error state
if 0 < drain_distance < 50: # Below 50 cm (Drained)
lcd.clear()
lcd.putstr("Water Drained\nClosing Valve")
set_servo_angle(servo2, 55) # Close Servo Motor 2
play_buzzer(1000, 0.2) # Short beep
time.sleep(2)
lcd.clear()
lcd.putstr("System Resetting")
time.sleep(2)
break # Exit draining process
for _ in range(3):
lcd.clear()
lcd.putstr("Draining:\n{} cm".format(drain_distance))
time.sleep(1)
rgb_color(0, 0, 1) # Green LED ON
time.sleep(1)
rgb_color(0, 0, 0) # Green LED ON
time.sleep(1)
break # Exit water level monitoring loop
else:
lcd.clear()
lcd.putstr("Waiting for Rain")
time.sleep(1) # Delay to avoid unnecessary processing
Loading
esp32-devkit-v1
esp32-devkit-v1