print("Project: Goal 9 (Industries, Innovation & Infrastructure)")
print("Program: Railway Crossing Safety System")
print("Created By: Muhammad Iqmal Najmi B. Zaidi")
# ---------------------------------------------------------------------------------------------
# Import Libraries
# ---------------------------------------------------------------------------------------------
from machine import Pin, SoftI2C, PWM, time_pulse_us
from time import sleep
import dht
from i2c_lcd import I2cLcd
# ---------------------------------------------------------------------------------------------
# Define the LCD I2C address and dimensions
# ---------------------------------------------------------------------------------------------
I2C_ADDR = 0x27
I2C_NUM_ROWS = 2
I2C_NUM_COLS = 16
# ---------------------------------------------------------------------------------------------
# Pin Definitions and Setup
# ---------------------------------------------------------------------------------------------
dht_sensor = dht.DHT11(Pin(4)) # Connect DHT11 data pin to GPIO15
i2c = SoftI2C(scl=Pin(22), sda=Pin(21), freq=400000) # Use GPIO22 (SCL) and GPIO21 (SDA)
lcd = I2cLcd(i2c, I2C_ADDR, I2C_NUM_ROWS, I2C_NUM_COLS)
trig_pin = Pin(13, Pin.OUT) # Ultrasonic sensor trigger pin
echo_pin = Pin(12, Pin.IN) # Ultrasonic sensor echo pin
servo_pin = PWM(Pin(14)) # Servo motor pin
servo_pin.freq(50)
red_signal = Pin(25, Pin.OUT) # Red LED
yellow_signal = Pin(26, Pin.OUT) # Yellow LED
green_signal = Pin(27, Pin.OUT) # Green LED
buzzer = PWM(Pin(16)) # Buzzer
buzzer.duty(0)
# ---------------------------------------------------------------------------------------------
# Direct Coding Logic
# ---------------------------------------------------------------------------------------------
try:
# Open gate initially
servo_pin.duty(int((0 / 180.0 * 102) + 26)) # Open gate (0 degrees)
red_signal.off()
yellow_signal.off()
green_signal.on()
print("System ready. Gate is open.")
while True:
# Read temperature and humidity from DHT11
try:
dht_sensor.measure()
temperature = dht_sensor.temperature()
humidity = dht_sensor.humidity()
except OSError as e:
print("Failed to read DHT sensor:", e)
temperature = None
humidity = None
# Measure distance using ultrasonic sensor
trig_pin.on()
sleep(0.00000001) # 10µs pulse
trig_pin.off()
pulse_time = time_pulse_us(echo_pin, 1) # Get pulse duration in microseconds
distance = pulse_time / 58.0 # Convert to distance in cm
print(f"Temperature: {temperature}, Humidity: {humidity}, Distance: {distance:.2f} cm")
# Display temperature and humidity/distance alternately
lcd.clear()
lcd.move_to(0, 0)
if temperature is not None:
lcd.putstr(f"Temp: {temperature:.1f}C")
else:
lcd.putstr("Temp: N/A")
lcd.move_to(0, 1)
if humidity is not None:
lcd.putstr(f"Hum: {humidity:.1f}%")
else:
lcd.putstr("Hum: N/A")
sleep(1) # Show humidity for 2 seconds
lcd.clear()
lcd.move_to(0, 0)
lcd.putstr(f"Dist: {distance:.2f}cm")
sleep(0.2) # Show distance for 2 seconds
# Check if object is detected (distance <= 10 cm)
if distance <= 10:
print("Object detected! Activating buzzer.")
buzzer.freq(1000)
buzzer.duty(512)
sleep(0.2)
buzzer.duty(0)
sleep(0.2)
print("Train approaching! Closing gate.")
lcd.clear()
lcd.move_to(0, 0)
lcd.putstr("Train Approaching!")
lcd.move_to(0, 1)
lcd.putstr("Gate Closing...")
red_signal.off()
yellow_signal.on()
green_signal.off()
# Beep with yellow LED
for Beep in range(5):
buzzer.freq(1000)
buzzer.duty(512)
sleep(0.2)
buzzer.duty(0)
sleep(0.2)
# Close the gate
servo_pin.duty(int((90 / 180.0 * 102) + 26)) # 90 degrees
print("Gate closing...")
sleep(2)
red_signal.on()
yellow_signal.off()
green_signal.off()
print("Gate is closed.")
# Beep with red LED after closure
for red in range(5):
buzzer.freq(1000)
buzzer.duty(512)
sleep(0.2)
buzzer.duty(0)
sleep(0.2)
# Wait until train departs (distance > 10 cm)
while distance <= 20:
trig_pin.on()
sleep(0.00000001)
trig_pin.off()
pulse_time = time_pulse_us(echo_pin, 1)
distance = pulse_time / 58.0
sleep(0.01)
print("Train departed. Opening gate.")
red_signal.off()
yellow_signal.off()
green_signal.on()
servo_pin.duty(int((0 / 180.0 * 102) + 26)) # Open gate (0 degrees)
lcd.clear()
lcd.move_to(0, 0)
lcd.putstr("Train Departed")
lcd.move_to(0, 1)
lcd.putstr("Gate Opening...")
sleep(2)
print("Gate is open.")
sleep(1) # Delay before checking again
except KeyboardInterrupt:
print("System shutting down.")
# Ensure system is in safe state
red_signal.off()
yellow_signal.off()
green_signal.on()
buzzer.duty(0)
servo_pin.duty(int((0 / 180.0 * 102) + 26)) # Open gate