# main.py (This is our Parking Monitor's Rulebook!)
# First, let's grab some tools we need from MicroPython's big toolbox.
from machine import Pin # This tool helps us use the ESP32's connection "pins".
import time # This tool lets us work with time, like adding small pauses.
# --- Setting Up Our Equipment (Configuration) ---
# We need to tell our ESP32 Brain which pin numbers connect to which parts.
# Think of these as addresses for each part.
# Button Pin Addresses:
ENTRY_BUTTON_PIN_NUM = 34 # The Green "Entry" button is at pin address 34.
EXIT_BUTTON_PIN_NUM = 35 # The Red "Exit" button is at pin address 35.
# LED Pin Addresses:
# Our 8 LEDs are connected to these pin addresses, in order from LED 1 to LED 8.
LED_PINS_NUM = [2, 4, 5, 13, 14, 16, 17, 18]
# Let's get some important numbers ready:
NUM_LEDS = len(LED_PINS_NUM) # MicroPython counts for us: this will be 8.
DEBOUNCE_MS = 50 # A tiny 50 millisecond pause. Why? Buttons can "bounce" when you press them,
# like a tiny trampoline, sending multiple quick signals. This pause helps us
# count just ONE press instead of many accidental ones!
MAX_CARS = NUM_LEDS # Our parking lot can hold a maximum of 8 cars (one for each LED).
# --- Our Brain's Memory (Global Variables) ---
# Variables are like named boxes where our ESP32 can store information that changes.
car_count = 0 # When we start, there are 0 cars in the parking lot. This is our main counter!
entry_button_last_state = 0 # Was the Entry button pressed last time we checked? (0=No, 1=Yes)
exit_button_last_state = 0 # Same for the Exit button.
last_entry_press_time = 0 # When was the Entry button properly pressed last? (Helps with DEBOUNCE_MS)
last_exit_press_time = 0 # Same for the Exit button.
# --- Getting Our Pins Ready for Action! (Pin Initialization) ---
# We tell each pin if it's an "INPUT" (listening for signals, like buttons)
# or an "OUTPUT" (sending out signals, like LEDs).
# Buttons are INPUTS: they send a "Hey, I'm pressed!" signal TO the ESP32.
entry_button = Pin(ENTRY_BUTTON_PIN_NUM, Pin.IN)
exit_button = Pin(EXIT_BUTTON_PIN_NUM, Pin.IN)
# LEDs are OUTPUTS: the ESP32 sends "Turn ON!" or "Turn OFF!" signals TO them.
leds = [] # Let's make an empty list to hold all our LED pin objects.
for current_pin_number in LED_PINS_NUM: # We'll go through each pin number in our LED_PINS_NUM list.
# For each one, tell the ESP32 it's an OUTPUT and add it to our 'leds' list.
leds.append(Pin(current_pin_number, Pin.OUT))
# --- Our Super Helper: The LED Light Show Function! ---
# A "function" is a named set of instructions that does one specific job.
# We can "call" this function by its name whenever we need it.
# This one, 'update_leds', will make sure the right number of LEDs are shining!
def update_leds():
# This 'for' loop will run 8 times (for i = 0, 1, 2, 3, 4, 5, 6, 7).
# 'i' is like a counter for which LED we are looking at (0 is the first LED, 1 is the second, etc.)
for i in range(NUM_LEDS):
if i < car_count: # If this LED's position number ('i') is less than our 'car_count'...
leds[i].on() # ...it means this LED should be ON! So, turn it ON.
else: # Otherwise (if its position number is NOT less than 'car_count')...
leds[i].off() # ...this LED should be OFF. So, turn it OFF.
# --- Let's Get This Party Started! (Initial State) ---
update_leds() # Call our helper function once right at the start.
# Since car_count is 0, this will make sure all LEDs are OFF. Perfect!
# Let's send some messages to the "Serial Monitor" in Wokwi.
# The Serial Monitor is like a little text screen where our ESP32 can "talk" to us.
print("🚀 Smart Parking Adventure - System Online!")
print(f"🅿️ Max Parking Spots: {MAX_CARS}")
print(f"🟢 Entry Button on Pin: GPIO{ENTRY_BUTTON_PIN_NUM}")
print(f"🔴 Exit Button on Pin: GPIO{EXIT_BUTTON_PIN_NUM}")
print(f"💡 LEDs (1-8) on Pins: {LED_PINS_NUM}")
# --- The Main Event: The Forever Loop! ---
# 'while True:' creates a loop that runs forever (or until we stop the simulation).
# Our ESP32 will keep doing these steps over and over, super fast!
while True:
current_time_ms = time.ticks_ms() # What time is it now, in milliseconds? (for our debounce trick)
# === Is a Car Entering? Let's Check the Green Button! ===
entry_button_current_state = entry_button.value() # Read the Entry button: Is it pressed (1) or not (0)?
# We only care if the button was JUST pressed.
# That means it wasn't pressed last time we checked (entry_button_last_state == 0)
# AND it IS pressed now (entry_button_current_state == 1).
if entry_button_current_state == 1 and entry_button_last_state == 0:
# Now for the debounce trick! Has enough time passed since the last good press?
if time.ticks_diff(current_time_ms, last_entry_press_time) > DEBOUNCE_MS:
# Hooray! A clean, debounced press!
if car_count < MAX_CARS: # Is there still room in our parking lot?
car_count = car_count + 1 # Yes! One more car. Increment the counter.
update_leds() # Time to update our LED scoreboard!
print(f"➡️ 🚗 Car ENTERED! Spots filled: {car_count}/{MAX_CARS}")
else: # Oh no, the parking lot is full!
print(f"🚫 Entry DENIED! Parking full ({car_count}/{MAX_CARS})")
last_entry_press_time = current_time_ms # Remember when this good press happened.
entry_button_last_state = entry_button_current_state # Remember the button's state for the next check.
# === Is a Car Exiting? Let's Check the Red Button! ===
exit_button_current_state = exit_button.value() # Read the Exit button.
if exit_button_current_state == 1 and exit_button_last_state == 0: # Just pressed?
if time.ticks_diff(current_time_ms, last_exit_press_time) > DEBOUNCE_MS: # Debounced?
# Yes, a clean exit press!
if car_count > 0: # Are there actually any cars to leave?
car_count = car_count - 1 # Yes! One less car. Decrement the counter.
update_leds() # Update the LED scoreboard!
print(f"⬅️ 🚗 Car EXITED! Spots filled: {car_count}/{MAX_CARS}")
else: # Hmm, trying to exit an empty parking lot?
print(f"🤔 Exit attempted. Parking already empty ({car_count}/{MAX_CARS})")
last_exit_press_time = current_time_ms # Remember this good press.
exit_button_last_state = exit_button_current_state # Remember for next time.
time.sleep_ms(20) # Take a super tiny nap (20 milliseconds).
# This gives our ESP32 a moment to breathe and keeps Wokwi happy.