from machine import Pin, I2C
import ssd1306
import time
CAPACITY = 20
btn_in = Pin(14, Pin.IN, Pin.PULL_UP)
btn_out = Pin(27, Pin.IN, Pin.PULL_UP)
led_green = Pin(2, Pin.OUT)
led_yellow = Pin(5, Pin.OUT)
led_red = Pin(4, Pin.OUT)
led_blue = Pin(18, Pin.OUT)
# OLED I2C: SDA = GPIO21, SCL = GPIO22-
i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=400000)
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
count = 0
# Variables for the non-blocking blue LED blink
blink_start_time = 0
is_blinking = False
def update_display():
oled.fill(0)
oled.text("PARKING GARAGE", 0, 0)
oled.text("Cars: " + str(count), 0, 20)
oled.text("Free: " + str(CAPACITY - count), 0, 35)
if count >= CAPACITY:
oled.text("FULL", 0, 50)
elif count >= CAPACITY - 2:
oled.text("NEARLY FULL", 0, 50)
else:
oled.text("AVAILABLE", 0, 50)
oled.show()
def update_status_leds():
if count >= CAPACITY:
# Garage is Full
led_green.value(0)
led_yellow.value(0)
led_red.value(1)
elif count >= CAPACITY - 2:
# Garage is Nearly Full (18 or 19 cars)
led_green.value(0)
led_yellow.value(1)
led_red.value(0)
else:
# Garage has plenty of space
led_green.value(1)
led_yellow.value(0)
led_red.value(0)
update_display()
# Start-up state
update_status_leds()
led_blue.value(0)
prev_in = 1
prev_out = 1
while True:
cur_in = btn_in.value()
cur_out = btn_out.value()
current_time = time.ticks_ms()
# 1. Handle non-blocking blue LED blink
if is_blinking and time.ticks_diff(current_time, blink_start_time) >= 300:
led_blue.value(0)
is_blinking = False
# 2. A car enters
if prev_in == 1 and cur_in == 0:
if count < CAPACITY:
count += 1
print("Car entered. Count =", count)
update_status_leds()
else:
print("Garage FULL. Entry ignored. Count =", count)
time.sleep_ms(50) # Debounce delay
# 3. A car exits
if prev_out == 1 and cur_out == 0:
if count > 0:
count -= 1
print("Car exited. Count =", count)
# Trigger the non-blocking blink instead of pausing the script
led_blue.value(1)
blink_start_time = time.ticks_ms()
is_blinking = True
update_status_leds()
else:
print("Garage EMPTY. Exit ignored. Count =", count)
time.sleep_ms(50) # Debounce delay
prev_in = cur_in
prev_out = cur_out
time.sleep_ms(10)