#=======================================================
# NAME: WAN KHALISH HAIKAL BIN WAN HARISS
# STUDENT ID: 52227124124
# Project: Smart Gate - Final Version with Distance Display
#=======================================================
import machine
import utime
import ssd1306
# --- Hardware Configuration ---
# I2C0: SDA=GP0 (Pin 1), SCL=GP1 (Pin 2)
i2c = machine.I2C(0, scl=machine.Pin(1), sda=machine.Pin(0), freq=400000)
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
# A4988 Stepper Driver: Step=GP14, Dir=GP15
step_pin = machine.Pin(14, machine.Pin.OUT)
dir_pin = machine.Pin(15, machine.Pin.OUT)
# HC-SR04 Ultrasonic Sensor: Trig=GP16, Echo=GP17
trig = machine.Pin(16, machine.Pin.OUT)
echo = machine.Pin(17, machine.Pin.IN)
# PIR Sensor: GP18
pir_pin = machine.Pin(18, machine.Pin.IN, machine.Pin.PULL_DOWN)
# --- Logic Constants ---
STEPS_PER_REV = 200
REV_LIMIT = 2
TOTAL_STEPS = STEPS_PER_REV * REV_LIMIT
STEP_DELAY = 1000
DIST_THRESHOLD = 20
# --- State Variables ---
current_dir = 0 # 0 for CW, 1 for CCW
def get_distance():
"""Calculates distance in cm using HC-SR04"""
trig.low()
utime.sleep_us(2)
trig.high()
utime.sleep_us(10)
trig.low()
# Wait for echo pulse
while echo.value() == 0:
signaloff = utime.ticks_us()
while echo.value() == 1:
signalon = utime.ticks_us()
timepassed = signalon - signaloff
distance = (timepassed * 0.0343) / 2
return distance
def update_display(status, detail, extra=""):
"""Handles OLED visual updates"""
oled.fill(0)
# Header
oled.text(" SMART GATE ", 10, 0)
oled.text("--------------", 8, 12)
# Content
oled.text(status, 0, 28)
oled.text(detail, 0, 42)
oled.text(extra, 0, 56)
oled.show()
# Serial Monitor Feedback
print(f"[LOG]: {status} | {detail} | {extra}")
# --- Main Program Boot ---
update_display("SYSTEM BOOT", "Pico W Active", "Ready...")
utime.sleep(1)
while True:
try:
dist = get_distance()
motion = pir_pin.value()
# Display current distance while scanning
dist_str = "Dist: {:.1f}cm".format(dist)
motion_str = "Motion: YES" if motion == 1 else "Motion: NO"
# Check triggers: Motion OR Proximity
if motion == 1 or dist < DIST_THRESHOLD:
source = "MOTION DETECTED" if motion == 1 else "SONIC TRIGGER"
action = "GATE OPENING" if current_dir == 0 else "GATE CLOSING"
update_display("!! ALERT !!", source, action)
# Execute Motor Rotation
dir_pin.value(current_dir)
for _ in range(TOTAL_STEPS):
step_pin.value(1)
utime.sleep_us(STEP_DELAY)
step_pin.value(0)
utime.sleep_us(STEP_DELAY)
update_display("TASK COMPLETE", "Cooldown...", "")
utime.sleep(2) # Prevent immediate re-trigger
# Toggle direction for next run
current_dir = 1 if current_dir == 0 else 0
else:
# Idle scanning mode - updates distance every 0.1s
update_display("STATUS: SCANNING", dist_str, motion_str)
utime.sleep(0.1)
except Exception as e:
print(f"Error in loop: {e}")
utime.sleep(1)Loading
pi-pico-w
pi-pico-w
Loading
ssd1306
ssd1306