from machine import Pin, ADC, PWM, SoftI2C
from time import sleep
import dht
from pico_i2c_lcd import I2cLcd
# ---------------- LCD ----------------
I2C_ADDR = 0x27
i2c = SoftI2C(sda=Pin(0), scl=Pin(1), freq=400000)
lcd = I2cLcd(i2c, I2C_ADDR, 2, 16)
# ---------------- DHT22 ----------------
dht_sensor = dht.DHT22(Pin(11))
# ---------------- PIR ----------------
pir = Pin(10, Pin.IN)
# ---------------- Servo (Door) ----------------
servo = PWM(Pin(12))
servo.freq(50)
# ---------------- Buzzer ----------------
buzzer = Pin(13, Pin.OUT)
# ---------------- Green LED ----------------
green_led = Pin(14, Pin.OUT)
# ---------------- RGB LED ----------------
red = Pin(17, Pin.OUT)
blue = Pin(18, Pin.OUT)
# ---------------- LDR ----------------
ldr = ADC(27)
# ---------------- MQ2 ----------------
mq2 = ADC(28)
# ---------------- Joystick ----------------
joy = ADC(26)
# ---------------- 4x4 Matrix Keypad ----------------
# Rows = OUTPUT, Columns = INPUT (pull-down)
# NOTE: confirm these GPIOs match your diagram.json wiring for the keypad
ROW_PINS = [Pin(2, Pin.OUT), Pin(3, Pin.OUT), Pin(4, Pin.OUT), Pin(5, Pin.OUT)]
COL_PINS = [Pin(6, Pin.IN, Pin.PULL_DOWN), Pin(7, Pin.IN, Pin.PULL_DOWN),
Pin(8, Pin.IN, Pin.PULL_DOWN), Pin(9, Pin.IN, Pin.PULL_DOWN)]
KEYS = [
['1', '2', '3', 'A'],
['4', '5', '6', 'B'],
['7', '8', '9', 'C'],
['*', '0', '#', 'D'],
]
PASSWORD = "1234"
entered = ""
def scan_keypad():
for r in range(4):
for rr in ROW_PINS:
rr.value(0)
ROW_PINS[r].value(1)
for c in range(4):
if COL_PINS[c].value() == 1:
while COL_PINS[c].value() == 1:
sleep(0.02) # simple debounce, wait for key release
return KEYS[r][c]
return None
# ---------------- Servo Function ----------------
def set_angle(angle):
duty = int(1638 + (angle / 180) * 6553)
servo.duty_u16(duty)
def beep(times=1, duration=0.1):
for _ in range(times):
buzzer.on()
sleep(duration)
buzzer.off()
sleep(duration)
def unlock_door():
lcd.clear()
lcd.putstr("ACCESS GRANTED")
beep(1, 0.15)
set_angle(180)
sleep(3)
set_angle(0)
lcd.clear()
def deny_access():
lcd.clear()
lcd.putstr("ACCESS DENIED")
beep(3, 0.1)
sleep(1)
lcd.clear()
# ---------------- Startup ----------------
lcd.clear()
lcd.putstr("SMART CLASS")
sleep(2)
lcd.clear()
lcd.putstr("SYSTEM READY")
sleep(2)
set_angle(0)
green_led.off()
red.off()
blue.off()
buzzer.off()
while True:
# ---------- Keypad (door lock) ----------
key = scan_keypad()
if key is not None:
if key == '#':
if entered == PASSWORD:
unlock_door()
else:
deny_access()
entered = ""
elif key == '*':
entered = "" # clear entry
lcd.clear()
else:
entered += key
lcd.clear()
lcd.move_to(0, 0)
lcd.putstr("Enter Code:")
lcd.move_to(0, 1)
lcd.putstr("*" * len(entered))
continue # skip sensor display this loop so keypad text stays visible
# ---------- DHT22 ----------
try:
dht_sensor.measure()
temp = dht_sensor.temperature()
hum = dht_sensor.humidity()
except:
temp = 0
hum = 0
# ---------- PIR ----------
motion = pir.value()
# ---------- LDR ----------
light = ldr.read_u16()
# ---------- MQ2 ----------
gas = mq2.read_u16()
# ---------- Joystick ----------
joy_value = joy.read_u16()
# ---------- LCD ----------
lcd.clear()
lcd.move_to(0, 0)
lcd.putstr("T:{}C H:{}%".format(temp, hum))
lcd.move_to(0, 1)
if motion:
lcd.putstr("Motion Detect")
buzzer.on()
red.on()
else:
buzzer.off()
red.off()
sleep(1)
# ---------- Green LED ----------
if light < 30000:
green_led.on()
else:
green_led.off()
# ---------- Gas ----------
if gas > 35000:
lcd.clear()
lcd.putstr("Gas Detected")
buzzer.on()
red.on()
else:
red.off()
# ---------- Temperature ----------
if temp > 30:
blue.on()
else:
blue.off()
# ---------- Servo (joystick manual override) ----------
if joy_value > 50000:
set_angle(180)
elif joy_value < 15000:
set_angle(0)
sleep(0.5)