from machine import Pin, I2C, PWM #PWM = Pulse Width Modulation
import time
import ssd1306
#Initialize I2C for OLED
i2c = I2C(0, scl=Pin(22), sda=Pin(21))
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
trig_pin = Pin(5, Pin.OUT) #Trigger pin for ultrasonic sensor
echo_pin = Pin(18, Pin.IN) #Echo pin for ultrasonic sensor
pir_pin = Pin(17, Pin.IN) #PIR motion sensor pin
led_green = Pin(32, Pin.OUT) #Green LED pin
led_yellow = Pin(25, Pin.OUT) #Yellow LED pin
led_red = Pin(27, Pin.OUT) #Red LED pin
buzzer = PWM(Pin(23), freq=1000, duty=0) #Buzzer pin with PWM
pir_motion_detected = False
def get_distance():
trig_pin.value(1)
time.sleep_us(10)
trig_pin.value(0)
#Measure the echo time
pulse_start = time.ticks_us()
while echo_pin.value() == 0:
pulse_start = time.ticks_us()
while echo_pin.value() == 1:
pulse_end = time.ticks_us()
pulse_duration = pulse_end - pulse_start
distance = (pulse_duration * 0.034) / 2
return distance
def display_message(distance, status1, status2):
oled.fill(0)
oled.text(f"Distance: {distance:.1f} cm", 0, 0) #Line 1
oled.text(status1, 0, 21) #Line 2
oled.text(status2, 0, 42) #Line 3
oled.show()
def beep(times):
for _ in range(times):
buzzer.duty(512)
time.sleep(0.1)
buzzer.duty(0)
time.sleep(0.1)
def pir_handler(pin):
global pir_motion_detected
pir_motion_detected = pin.value() == 1
pir_pin.irq(trigger=Pin.IRQ_RISING | Pin.IRQ_FALLING, handler=pir_handler)
while True:
distance = get_distance()
if distance <= 100:
led_red.value(1)
led_yellow.value(0)
led_green.value(0)
buzzer.duty(512) #Buzzer on continously
display_message(distance, " CRITICAL AREA!", " DANGER!!")
elif 101 <= distance <= 250:
led_red.value(0)
led_yellow.value(1)
led_green.value(0)
buzzer.duty(0)
if pir_motion_detected:
beep(2) #Buzzer beep 2 times
display_message(distance, " Animal entered", " CAUTION ZONE!!")
else:
led_green.value(1)
led_yellow.value(0)
led_red.value(0)
buzzer.duty(0)
display_message(distance, " Animal is in", " SAFE ZONE")
time.sleep(1)