import time
import utime
from machine import Pin, PWM, I2C, time_pulse_us
# ------------------------------
# LCD INITIALIZATION
# ------------------------------
# I2C pins: SDA=GP20, SCL=GP17
i2c = I2C(0, scl=Pin(17), sda=Pin(20), freq=400000)
LCD_I2C_ADDR = 0x27 # Common address for PCF8574 I2C LCD
# LCD commands
LCD_CLR = 0x01
LCD_HOME = 0x02
LCD_LINE_1 = 0x80
LCD_LINE_2 = 0xC0
LCD_BACKLIGHT = 0x08
ENABLE = 0b00000100
def lcd_strobe(data):
i2c.writeto(LCD_I2C_ADDR, bytes([data | ENABLE | LCD_BACKLIGHT]))
utime.sleep_us(500)
i2c.writeto(LCD_I2C_ADDR, bytes([(data & ~ENABLE) | LCD_BACKLIGHT]))
utime.sleep_us(100)
def lcd_write(data, mode=0):
high = mode | (data & 0xF0) | LCD_BACKLIGHT
low = mode | ((data << 4) & 0xF0) | LCD_BACKLIGHT
i2c.writeto(LCD_I2C_ADDR, bytes([high]))
lcd_strobe(high)
i2c.writeto(LCD_I2C_ADDR, bytes([low]))
lcd_strobe(low)
def lcd_clear():
lcd_write(LCD_CLR)
utime.sleep_ms(2)
def lcd_init():
lcd_write(0x33)
lcd_write(0x32)
lcd_write(0x28)
lcd_write(0x0C)
lcd_write(0x06)
lcd_write(LCD_CLR)
utime.sleep_ms(2)
def lcd_print(message):
"""
Prints any message (up to 32 characters) to a 16x2 LCD.
Line 1 = first 16 chars
Line 2 = next 16 chars
"""
lcd_clear()
line1 = message[0:16]
line2 = message[16:32]
lcd_write(LCD_LINE_1)
for c in line1:
lcd_write(ord(c), mode=1)
lcd_write(LCD_LINE_2)
for c in line2:
lcd_write(ord(c), mode=1)
# Initialize LCD
lcd_init()
# ------------------------------
# SYSTEM INITIALIZATION
# ------------------------------
lcd_print("System Booting...")
time.sleep(1)
# LED Init
#Test for the code to know either ultrasonic sensor working or not
#Built In Pico LED
led = Pin("LED", Pin.OUT)
led.value(1)
time.sleep(0.5)
led.value(0)
# External LED on GP28 to know the code can run
#Samuel u can remove this untill
led = Pin(28, Pin.OUT)
led.value(True)
time.sleep(1)
led.value(False)
time.sleep(1)
#here in the final program
lcd_print("System Ready")
time.sleep(1)
# Define car in each slot
areaa = ["DEA69", "DAD6969", "DBE6969", "DDB6969"]
areab = ['JUG6969', 'USM1069', 'DAV1869']
# Ultrasonic pins
# Define GPIO pins for the ultrasonic sensor (adjust these if you used different pins)
TRIGGER_PIN = 3
ECHO_PIN = 2
trigger = Pin(TRIGGER_PIN, Pin.OUT)
echo = Pin(ECHO_PIN, Pin.IN)
# PIR Sensor on GP15
# Define GPIO pins for the pir (adjust these if you used different pins)
pir = Pin(15, Pin.IN)
# Servo motor
# Define GPIO pins for the servo motor (adjust these if you used different pins)
servo_pin = Pin(19)
pwm = PWM(servo_pin)
# Set Duty Cycle for Different Angles
max_duty = 7864 # 180degrees=Not Used by us
min_duty = 1802 # Open=0degrees---use this for open
close_duty = 5000 # close=90degrees---use this for close
pwm.freq(50) # Set PWM frequency-pwm.freq(frequency value)
# Start with gate CLOSED
pwm.freq(50)
pwm.duty_u16(close_duty)
time.sleep(2)
# ------------------------------
# CAR PASSED FUNCTION (PIR)
#When using the slide switch
#Slide right = Car Detected at gate = Car has not passed the gate yet
#Slide left = Car passed pir
# ------------------------------
def get_car_passed():
return pir.value() == 0
# ------------------------------
# ULTRASONIC FUNCTION
# ------------------------------
def get_car_sensor():
def get_distance():
trigger.low()
utime.sleep_us(2)
trigger.high()
utime.sleep_us(10)
trigger.low()
try:
duration = time_pulse_us(echo, 1, 30000)
if duration < 0:
return -1
distance = (duration * 0.0343) / 2
return distance
except OSError:
return -1
dist = get_distance()
if dist >= 0:
return dist < 20
return False
# ------------------------------
# MAIN LOOP
# ------------------------------
while True:
cs = get_car_sensor()
if cs:
lcd_print("Car Detected!")
time.sleep(1)
car_plate = input("Enter plate number: ")
lcd_print("Plate: " + car_plate)
time.sleep(1)
if car_plate in areaa:
#For parking area A elif below need to be both False
lista = True
listb = False
elif car_plate in areab:
#For parking area B elif above need to be both False
listb = True
lista = False
else:
lista = False
listb = False
if lista:
lcd_print("Welcome to Area A")
pwm.duty_u16(min_duty)
time.sleep(1)
elif listb:
lcd_print("Welcome to Area B")
pwm.duty_u16(min_duty)
time.sleep(1)
else:
lcd_print("No Entry - Unknown Plate")
pwm.duty_u16(close_duty)
time.sleep(2)
continue # restart loop (no gate movement)
# Wait for PIR
lcd_print("Go to your parking slot")
while True:
if get_car_passed():
lcd_print("Car Passed")
break
time.sleep(0.1)
continue # restart loop ( car still at the gate)
# After PIR detects passing → close gate
pwm.duty_u16(close_duty)
lcd_print("Gate Closed")
time.sleep(2)
else:
# No car detected by ultrasonic → keep gate closed
pwm.duty_u16(close_duty)
lcd_print("No Car Detected Gate Closed")
time.sleep(1)