# === Wokwi-Compatible MicroPython Code ===
from machine import Pin, I2C
from time import sleep, sleep_us, ticks_us, ticks_diff
from pico_i2c_lcd import I2cLcd
# === Setup I2C LCD ===
i2c = I2C(0, scl=Pin(1), sda=Pin(0), freq=400000)
lcd = I2cLcd(i2c, 0x27, 2, 16)
# === LEDs ===
led_green = Pin(12, Pin.OUT)
led_red = Pin(13, Pin.OUT)
# === Buzzer ===
buzzer = Pin(15, Pin.OUT)
# === Push Buttons ===
door_button = Pin(9, Pin.IN, Pin.PULL_UP)
emergency_button = Pin(10, Pin.IN, Pin.PULL_UP)
weight_button = Pin(11, Pin.IN, Pin.PULL_UP)
# === Ultrasonic Sensor (HC-SR04) ===
ultra_trig = Pin(14, Pin.OUT)
ultra_echo = Pin(28, Pin.IN)
# === Keypad ===
row_pins = [Pin(16, Pin.OUT), Pin(17, Pin.OUT), Pin(18, Pin.OUT), Pin(19, Pin.OUT)]
col_pins = [Pin(20, Pin.IN, Pin.PULL_DOWN), Pin(21, Pin.IN, Pin.PULL_DOWN), Pin(22, Pin.IN, Pin.PULL_DOWN)]
keys = [
['1', '2', '3'],
['4', '5', '6'],
['7', '8', '9'],
['*', '0', '#']
]
# === 7-Segment Display (Common Anode with DP) ===
seg_pins = [Pin(2, Pin.OUT), Pin(3, Pin.OUT), Pin(4, Pin.OUT), Pin(5, Pin.OUT), Pin(6, Pin.OUT), Pin(7, Pin.OUT), Pin(8, Pin.OUT)]
dp = Pin(11, Pin.OUT)
segments = {
'0': [0,0,0,0,0,0,1],
'1': [1,0,0,1,1,1,1],
'2': [0,0,1,0,0,1,0],
'3': [0,0,0,0,1,1,0],
'4': [1,0,0,1,1,0,0],
'5': [0,1,0,0,1,0,0],
'6': [0,1,0,0,0,0,0],
'7': [0,0,0,1,1,1,1],
'8': [0,0,0,0,0,0,0],
'9': [0,0,0,0,1,0,0],
' ': [1,1,1,1,1,1,1]
}
def display_digit(digit, dot=False):
pattern = segments.get(digit, segments[' '])
for seg, val in zip(seg_pins, pattern):
seg.value(val)
dp.value(dot)
def clear_7seg():
for seg in seg_pins:
seg.value(1)
dp.value(1)
def read_distance():
ultra_trig.value(0)
sleep_us(2)
ultra_trig.value(1)
sleep_us(10)
ultra_trig.value(0)
while ultra_echo.value() == 0:
pass
start = ticks_us()
while ultra_echo.value() == 1:
pass
end = ticks_us()
duration = ticks_diff(end, start)
return (duration / 2) / 29.1
def scan_keypad():
for i, row in enumerate(row_pins):
for r in row_pins:
r.value(0)
row.value(1)
for j, col in enumerate(col_pins):
if col.value():
sleep(0.2)
return keys[i][j]
return None
def buzzer_on(duration=0.5):
buzzer.value(1)
sleep(duration)
buzzer.value(0)
def open_then_auto_close_door(duration=5):
led_green.value(1)
led_red.value(0)
lcd.clear()
lcd.putstr("Door Opening")
buzzer_on(0.5)
for sec in range(duration, 0, -1):
display_digit(str(sec))
sleep(1)
clear_7seg()
led_green.value(0)
led_red.value(1)
lcd.clear()
lcd.putstr("Door Closing")
sleep(2)
def go_to_floor(floor):
global current_floor
lcd.clear()
lcd.putstr(f"Going to {floor}")
sleep(1)
current_floor = floor
lcd.clear()
lcd.putstr(f"Arrived at {current_floor}")
buzzer_on(0.5)
sleep(1)
open_then_auto_close_door()
def handle_emergency():
lcd.clear()
lcd.putstr("!!! EMERGENCY !!!")
led_green.value(0)
led_red.value(1)
clear_7seg()
while emergency_button.value() == 0:
sleep(0.1)
lcd.clear()
lcd.putstr("Hold to Reset...")
hold_time = 0
while emergency_button.value():
sleep(0.1)
while emergency_button.value() == 0:
hold_time += 0.1
sleep(0.1)
if hold_time >= 3:
lcd.clear()
lcd.putstr("Reset Complete")
sleep(1)
lcd.clear()
lcd.putstr(f"At Floor {current_floor}")
return
def handle_weight():
global buzzer_active
if weight_button.value() == 0:
if not buzzer_active:
buzzer_active = True
buzzer.value(1)
lcd.clear()
lcd.putstr("Full Load Detected!")
else:
buzzer_active = False
buzzer.value(0)
lcd.clear()
lcd.putstr("Load Reset!")
sleep(0.5)
# === Initial State ===
current_floor = '0'
buzzer_active = False
last_button = 1
led_red.value(1)
led_green.value(0)
lcd.clear()
lcd.putstr("At Ground Floor")
clear_7seg()
# === Main Loop ===
while True:
if emergency_button.value() == 0:
handle_emergency()
continue
handle_weight()
distance = read_distance()
if distance and distance < 30:
lcd.clear()
lcd.putstr("Object Detected!")
open_then_auto_close_door()
sleep(2)
key = scan_keypad()
if key and key.isdigit():
go_to_floor(key)
current_button = door_button.value()
if last_button and not current_button:
open_then_auto_close_door()
last_button = current_button
sleep(0.05)