import machine
from machine import Pin, PWM, I2C, ADC
from time import sleep, ticks_ms, ticks_diff
import ssd1306
# --- 1. Hardware Setup ---
gled = Pin(15, Pin.OUT)
rled = Pin(13, Pin.OUT)
tin = Pin(16, Pin.IN, Pin.PULL_UP)
ir_sensor = ADC(26)
pir_sensor = Pin(22, Pin.IN) # Signal on Pin 22
exit_button = Pin(18, Pin.IN, Pin.PULL_UP)
alarm = Pin(17, Pin.IN, Pin.PULL_UP)
mot=Pin(20,Pin.OUT)
# I2C/OLED Setup
i2c = I2C(0, scl=Pin(1), sda=Pin(0), freq=400000)
oled = ssd1306.SSD1306_I2C(128, 64, i2c, 0x3c)
# Servo Setup
servo = PWM(Pin(10))
servo.freq(50)
# Buzzer Setup
buzzer = PWM(Pin(14))
buzzer.freq(1000)
# Keypad Mapping
keypad = [
['1', '2', '3', 'A'],
['4', '5', '6', 'B'],
['7', '8', '9', 'C'],
['*', '0', '#', 'D']
]
rows = [Pin(2, Pin.OUT), Pin(3, Pin.OUT), Pin(4, Pin.OUT), Pin(5, Pin.OUT)]
cols = [Pin(6, Pin.IN, Pin.PULL_UP), Pin(7, Pin.IN, Pin.PULL_UP), Pin(8, Pin.IN, Pin.PULL_UP), Pin(9, Pin.IN, Pin.PULL_UP)]
# --- 2. Functions ---
def move_servo(angle):
if angle == 90:
servo.duty_ns(1500000)
else:
servo.duty_ns(500000)
sleep(0.5)
servo.duty_ns(0)
# --- 3. Initialize ---
correct_password = "2510"
last_trigger_time = 0 # To handle the SR505 8-second delay
move_servo(0)
oled.fill(0)
oled.text("SYSTEM BOOTING", 10, 25)
oled.show()
mot.value(1)
sleep(3) # Initial calibration wait for PIR
oled.fill(0)
oled.text("System Started", 10, 25)
oled.show()
mot.value(0)
sleep(1)
# --- 4. Main Program Loop ---
while True:
# A. Check Alarm Pin
if alarm.value() == 1:
buzzer.duty_u16(30000)
mot.value(1)
else:
buzzer.duty_u16(0)
mot.value(0)
# B. Check Manual Exit Button
if exit_button.value() == 1: # Logic for PULL_UP (0 = Pressed)
oled.fill(0)
oled.text("Manual Release", 0, 0)
oled.show()
move_servo(90)
gled.value(1)
mot.value(1)
sleep(3)
mot.value(0)
move_servo(0)
gled.value(0)
oled.fill(0)
oled.show()
# C. Check Sensors (IR and PIR)
ir_value = ir_sensor.read_u16()
motion_detected = pir_sensor.value()
# COOLDOWN LOGIC: Only trigger if 10 seconds have passed since last activation
# This prevents the SR505's fixed 8s "HIGH" pulse from re-triggering the system.
if (ir_value > 3800 or motion_detected == 1) and tin.value() == 1:
if ticks_diff(ticks_ms(), last_trigger_time) > 10000:
oled.fill(0)
oled.text("Human Detected", 5, 0)
oled.text("Enter PIN:", 15, 16)
oled.show()
password = ""
count = 0
while count < 4:
for row_num, row in enumerate(rows):
row.value(0)
for col_num, col in enumerate(cols):
if col.value() == 0:
key = keypad[row_num][col_num]
if key.isdigit():
password += key
count += 1
oled.fill(0)
oled.text("Enter: " + "*" * count, 10, 30)
oled.show()
buzzer.duty_u16(1000)
mot.value(1)
sleep(0.5)
buzzer.duty_u16(0)
mot.value(0)
sleep(0.3)
row.value(1)
sleep(0.05)
if password == correct_password:
oled.fill(0)
oled.text("Access Granted!", 10, 30)
oled.show()
move_servo(90)
gled.value(1)
mot.value(1)
sleep(3)
mot.value(0)
move_servo(0)
gled.value(0)
else:
oled.fill(0)
oled.text("Access Denied!", 10, 30)
oled.show()
rled.value(1)
mot.value(1)
buzzer.duty_u16(30000)
sleep(1)
mot.value(0)
buzzer.duty_u16(0)
rled.value(0)
last_trigger_time = ticks_ms() # Update cooldown timer
oled.fill(0)
oled.show()
sleep(1)
else:
# D. Idle State
oled.fill(0)
oled.text("System Armed", 15, 20)
oled.text("Waiting...", 20, 35) # Reduced flickering
oled.show()
sleep(0.1)