from machine import Pin, PWM, I2C
from time import sleep, ticks_us, ticks_diff
from dht import DHT22
from ssd1306 import SSD1306_I2C # OLED library for SSD1306
# Initialize OLED display
i2c = I2C(0, scl=Pin(22), sda=Pin(21)) # Adjust pins for Wokwi
oled = SSD1306_I2C(128, 64, i2c) # OLED resolution 128x64
# Input pins
pir_sensor = Pin(14, Pin.IN) # PIR motion sensor
dht_sensor = DHT22(Pin(4)) # DHT22 temperature and humidity sensor
trig = Pin(12, Pin.OUT) # Ultrasonic trigger pin
echo = Pin(13, Pin.IN) # Ultrasonic echo pin
# Output pins
buzzer = Pin(27, Pin.OUT) # Buzzer
led = Pin(25, Pin.OUT) # LED
servo = PWM(Pin(15), freq=50) # Servo motor (PWM)
# Function to set servo angle (0 to 180 degrees)
def set_servo_angle(angle):
duty = int(40 + (angle / 180) * 115) # Map angle to PWM duty cycle
servo.duty(duty)
# Function to measure distance using ultrasonic sensor
def measure_distance():
trig.value(0)
sleep(0.002) # Stabilize trigger pin
trig.value(1)
sleep(0.01) # Send 10us pulse
trig.value(0)
while echo.value() == 0:
start_time = ticks_us() # Start timing
while echo.value() == 1:
end_time = ticks_us() # End timing
duration = ticks_diff(end_time, start_time) # Pulse duration in microseconds
distance = (duration / 2) * 0.0343 # Convert to cm
return distance
# Initial setup
set_servo_angle(0) # Servo at 0 degrees (door closed)
buzzer.value(0)
led.value(0)
oled.fill(0)
oled.show()
# Main loop
while True:
# Read sensors
motion_detected = pir_sensor.value() # PIR sensor reading
distance = measure_distance() # Ultrasonic distance in cm
try:
dht_sensor.measure()
temperature = dht_sensor.temperature() # Temperature in °C
except OSError:
temperature = None
# CASE 1: Both PIR and Ultrasonic detect
if motion_detected and distance < 15:
print("DOOR OPEN")
oled.fill(0)
oled.text("DOOR OPEN", 0, 0)
oled.show()
led.value(1) # Turn on LED
buzzer.value(1) # Turn on buzzer
set_servo_angle(60) # Open the door
sleep(5) # Wait 5 seconds
set_servo_angle(0) # Close the door
buzzer.value(0) # Turn off buzzer
led.value(0) # Turn off LED
# CASE 2: PIR only
elif motion_detected:
print("MOTION DETECTED")
oled.fill(0)
oled.text("MOTION DETECTED", 0, 0)
oled.show()
led.value(1) # Turn on LED
sleep(5) # Wait 5 seconds
led.value(0) # Turn off LED
# CASE 3: Ultrasonic only
elif distance < 15:
print("THERE'S SOMEONE AT THE DOOR")
oled.fill(0)
oled.text("SOMEONE AT DOOR", 0, 0)
oled.show()
led.value(1) # Turn on LED
sleep(5) # Wait 5 seconds
led.value(0) # Turn off LED
# CASE 4: High temperature
if temperature is not None and temperature > 30:
print(f"High Temp: {temperature}°C")
oled.fill(0)
oled.text(f"Temp: {temperature:.1f}C", 0, 0)
oled.show()
led.value(1) # Turn on LED
buzzer.value(1) # Buzzer short beep
sleep(0.01)
buzzer.value(0) # Turn off buzzer
else:
led.value(0) # Turn off LED for normal temperature
# Clear OLED if no conditions are met
if not motion_detected and distance >= 15 and (temperature is None or temperature <= 30):
oled.fill(0)
oled.show()
sleep(0.5) # Delay for loop stability