from machine import Pin, PWM, ADC, time_pulse_us
import time
import dht
from time import ticks_ms, ticks_diff
from neopixel import NeoPixel
seg_a = Pin(15, Pin.OUT)
seg_b = Pin(0, Pin.OUT)
seg_c = Pin(33, Pin.OUT)
seg_d = Pin(12, Pin.OUT)
seg_e = Pin(27, Pin.OUT)
seg_f = Pin(21, Pin.OUT)
seg_g = Pin(14, Pin.OUT)
button = Pin(2, Pin.IN, Pin.PULL_UP)
servo = PWM(Pin(18), freq = 50)
dht_sensor = dht.DHT22(Pin(13))
pir_motion_sensor = Pin(34, Pin.IN)
ldr = ADC(Pin(26))
gas_sensor = ADC(Pin(32))
trig_pin = Pin(23, Pin.OUT)
echo_pin = Pin(22, Pin.IN)
buzzer = PWM(Pin(4))
servo.duty_u16(90)
RE_clk = Pin(5, Pin.IN)
RE_dt = Pin(17, Pin.IN)
led = Pin(25, Pin.OUT)
neopixel = NeoPixel(Pin(16), 8)
ambient_light_classes = [
(1000, "Dark"),
(2500, "Dim"),
(float("inf"), "Sunlight"),
]
temp_classes = [
(35, 0), # "Normal"
(44, 1), # "Hot"
(float("inf"), 2), # Critical
]
gas_classes = [
(1200, 0), # "Normal"
(2200, 1), # "Slighlt_pollution"
(float("inf"), 2), # "High_pollution"
]
digits = {
0: "abcdef",
1: "bc",
2: "abdeg",
3: "abcdg",
4: "bcfg",
5: "acdfg",
6: "acdefg",
7: "abc",
8: "abcdefg",
}
pins = {
"a": seg_a,
"b": seg_b,
"c": seg_c,
"d": seg_d,
"e": seg_e,
"f": seg_f,
"g": seg_g
}
fan_modes = ["OFF", "LOW", "MED", "HIGH"]
last_button_state = 1
Emergency_start_time = 0
flash_state = False
lights_state = False
temp_states = ["Normal", "Hot", "Critical"]
gas_states = ["Normal", "Slight Pollution", "High Pollution"]
light_state = None
below_100_count = 0
parking_system_start_time = None
beep_on = False
buzzer_timer = ticks_ms()
buzzer.freq(1000)
buzzer.duty_u16(0)
message_printed = False
user_request = False
last_status = None
last_debounce_time = ticks_ms()
last_debounce_time_rotary = time.ticks_ms()
timeout = False
dis_now = None
last_dis = None
lighting_system_start_time = None
gate_timer = None
pir_State = 0
servo.duty_u16(1802)
start_time = ticks_ms()
input_start_time = ticks_ms()
rotary_encoder_start_time = ticks_ms()
car_detected = False
gate_open = False
parked_cars = 0
#Car_pos = 1, = enter | = 0, = exit
car_pos = None
last_clk = RE_clk.value()
GAMMA = 0.7
RL10 = 50
def get_distance():
global distance_cm
# Send the signel to the trig pin to start the measurements
trig_pin.value(0)
time.sleep_us(2)
trig_pin.value(1)
time.sleep_us(10)
trig_pin.value(0)
#handel timeout
try:
duration = time_pulse_us(echo_pin, 1, 30000)
except OSError:
return None
new_distance = round(340 * duration / 20000)
# Ignore invalid readings
if new_distance <= 0 or new_distance > 400:
return None
distance_cm = new_distance
return distance_cm
def environmental_sensors_reading():
global lux, average, dht_temperature
#LDR Formula taken from wokwi
try:
ldr_analogValue = ldr.read()
voltage = ldr_analogValue / 4095 * 5
resistance = 2000 * voltage / (1 - voltage / 5)
lux = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA))
except Exception as e:
lux = 0
print("Error Reading LDR", e)
#print("Lux:", round(lux))
#DHT22 Logic
try:
dht_sensor.measure()
dht_temperature= dht_sensor.temperature()
except Exception as e:
dht_temperature = 0
print("Error Reading DHT", e)
#print(f"Temperature: {dht_temperature:.1f}°C")
#Gas Sensor (MQ2) Logic
gas_sensor_analogValue_list = []
try:
for _ in range(5):
gas_sensor_analogValue_list.append(gas_sensor.read())
average = sum(gas_sensor_analogValue_list) / len(gas_sensor_analogValue_list)
except Exception as e:
average = 0
print("Error Reading Gas sensor", e)
#print(average)
return lux, average, dht_temperature
def parking_logic(dis_now):
global gate_open, parked_cars, car_detected,car_pos
global gate_timer, last_dis, timeout
global user_request, message_printed
global below_100_count
if dis_now <= 100:
below_100_count += 1
else:
below_100_count = 0
if below_100_count >= 2 and dis_now != last_dis:
last_dis = dis_now
car_detected = True
gate_timer = ticks_ms()
message_printed = False
if below_100_count >= 2:
if user_request == True and car_pos != None:
if car_pos == 0 and parked_cars == 0:
print("No cars in the garage. Exit denied.")
user_request = False
car_detected = True
return
if parked_cars == 8 and car_pos == 1:
print("Garage is Full")
user_request = False
car_detected = True
return
elif not gate_open:
servo.duty_u16(4833)
gate_open = True
timeout = False
gate_timer = ticks_ms()
if car_detected == True:
if car_pos == 1 and parked_cars < 8:
print("Car entered")
parked_cars += 1
seven_segement_logic(parked_cars)
elif car_pos == 0 and parked_cars > 0:
print("Car left")
parked_cars -= 1
seven_segement_logic(parked_cars)
car_detected = False
user_request = False
car_pos = None
elif message_printed == False:
print("Waiting for direction...")
message_printed = True
else:
if gate_open:
servo.duty_u16(1802)
gate_open = False
car_detected = False
def motion_system():
global pir_State
if pir_motion_sensor.value() == 1:
if pir_State == 0:
pir_State = 1
elif pir_motion_sensor.value() == 0:
if pir_State == 1:
pir_State = 0
lighting_system(lux)
def lighting_system(lux):
global lighting_system_start_time, light_state, lights_state
light_state = None
for upper_limit, state in ambient_light_classes:
if lux <= upper_limit:
light_state = state
break
if pir_State == 1 and light_state in ("Dark", "Dim"):
if lighting_system_start_time is None:
lighting_system_start_time = ticks_ms()
lights_state = True
led.on()
elif light_state in ("Sunlight") and lighting_system_start_time is None:
lighting_system_start_time = None
lights_state = False
led.off()
def vent_logic(average, dht_temperature):
global gas_level, temp_level, fan_speed
for limit, index in gas_classes:
if average <= limit:
gas_level = index
break
for limit, index in temp_classes:
if dht_temperature <= limit:
temp_level = index
break
if temp_level == 2 or gas_level == 2:
fan_speed = fan_modes[3] # HIGH
elif temp_level == 1 and gas_level == 1:
fan_speed = fan_modes[2] # MED
elif temp_level == 1 or gas_level == 1:
fan_speed = fan_modes[1] # LOW
else:
fan_speed = fan_modes[0] # OFF
def hazard_logic():
global status, index_hazards, last_status, hazards, flash_state, Emergency_start_time
hazards = (temp_level == 2) + (gas_level == 2)
if parked_cars >= 6:
hazards += 1
index_hazards = min(hazards, 2)
status = ["Normal", "Warning", "Emergency"][index_hazards]
if status == "Normal":
color = (0, 255, 0) # Green
elif status == "Warning":
color = (255, 255, 0) # Yellow
elif status == "Emergency":
if ticks_diff(ticks_ms(), Emergency_start_time) >= 500: # 500ms
flash_state =not flash_state
Emergency_start_time = ticks_ms()
if flash_state:
color = (255, 0, 0) # Red ON
else:
color = (0, 0, 0)
if last_status != status:
dash_board()
else:
color = (0, 0, 0) # Off
for i in range(len(neopixel)):
neopixel[i] = color
neopixel.write()
buzzer_logic(status)
last_status = status
def buzzer_logic(status):
global buzzer_timer, beep_on
now = ticks_ms()
if status == "Normal":
interval = 0
freq = 1000
buzzer.duty_u16(0)
elif status == "Warning":
interval = 0
freq = 1000
buzzer.duty_u16(0)
elif status == "Emergency":
interval = 250
freq = 2000
if ticks_diff(now, buzzer_timer) >= interval and status == "Emergency":
buzzer_timer = now
if beep_on:
buzzer.duty_u16(0)
beep_on = False
else:
buzzer.freq(freq)
buzzer.duty_u16(30000)
beep_on = True
def seven_segement_logic(number):
active = digits[number]
for name, pin in pins.items():
if name in active:
pin.value(1)
else:
pin.value(0)
def button_check():
global last_debounce_time, last_button_state
state = button.value()
if state != last_button_state:
if ticks_diff(ticks_ms(), last_debounce_time) >= 100:
last_debounce_time = ticks_ms()
last_button_state = state
if state == 0:
dash_board()
last_button_state = state
def dash_board():
warnings = []
if temp_level == 2:
warnings.append("High Temperature Warning")
if gas_level == 2:
warnings.append("Air Quality Warning")
if parked_cars >= 6:
warnings.append("High number of cars Warning")
Warning_Type = ", ".join(warnings) if warnings else "No Warnings"
if status != "Emergency":
print(f"""
============================================================
SMART PARKING DASHBOARD
============================================================
Car Detected? : {car_detected}
Distance : {distance_cm:6.1f} cm
Light Level : {round(lux):6} lux , {light_state}
Temperature : {dht_temperature:6.1f} °C, {temp_states[temp_level]}
Gas Level : {average:6}, {gas_states[gas_level]}
Parking Occupancy : {parked_cars:6}
Gate Open? : {gate_open}
Fan Speed : {fan_speed}
Hazards Detected : {hazards}
Lights On? : {lights_state}
============================================================
SYSTEM STATUS
============================================================
{status} , {Warning_Type}
============================================================
""")
if status == "Emergency":
print(f"""
============================================================
SMART PARKING DASHBOARD
============================================================
Temperature : {dht_temperature:6.1f} °C, {temp_states[temp_level]}
Gas Level : {average:6}, {gas_states[gas_level]}
Parking Occupancy : {parked_cars:6}
Gate Open? : {gate_open}
Fan Speed : {fan_speed}
Hazards Detected : {hazards}
============================================================
SYSTEM STATUS
============================================================
{status} , {Warning_Type}
============================================================
""")
print("Program Starting.......")
environmental_sensors_reading()
lighting_system(lux)
vent_logic(average, dht_temperature)
print("Systems are Functional")
print("Program Ready")
last_ultrasonic_read = ticks_ms()
seven_segement_logic(0)
while True:
new_clk = RE_clk.value()
if new_clk != last_clk:
last_clk = new_clk
if ticks_diff(ticks_ms(), rotary_encoder_start_time) >= 50:
rotary_encoder_start_time = ticks_ms()
if new_clk == 0:
if RE_dt.value() == 1:
car_pos = 1
user_request = True
elif RE_dt.value() == 0:
car_pos = 0
user_request = True
else:
car_pos = None
else:
car_pos = None
button_check()
if ticks_diff(ticks_ms(), start_time) >= 500:
environmental_sensors_reading()
motion_system()
vent_logic(average, dht_temperature)
hazard_logic()
start_time = ticks_ms()
if lighting_system_start_time != None and ticks_diff(ticks_ms(), lighting_system_start_time) >= 20000:
lights_state = False
led.off()
lighting_system_start_time = None
if ticks_diff(ticks_ms(), last_ultrasonic_read) >= 200:
last_ultrasonic_read = ticks_ms()
reading = get_distance()
if reading is not None:
parking_logic(reading)
if ticks_diff(ticks_ms(), gate_timer) >= 30000 and last_dis == dis_now and timeout == False and servo.duty_u16() != 1802:
servo.duty_u16(1802)
gate_open = False
timeout = True
print("30 sec passed. Closing Barrier.")