Code

Pre-requisites

  1. Install the latest version of Thony IDE from the internet.

  2. Raspberry Pico Interpreter: Once installed connect to laptop to the raspberry pico while holding the boot button so as to install the files. Then click on run in Thony IDE. After that select the micropython Raspberry Pico interpreter, select the port and install.

Smart Traffic Signal (microPython)

smart_traffic_signal.py
#-------------Libraries------------#
import machine
import time
 
#--------Pin Mapping --------------#
# When using Fritzing, look for pin function (GP1, VCC, CND) and not pin number.
 
# For South-North traffic flow signal (see note on circuit diagram)
 
# START CHANGE BY STEMVentor
 
# RED1 = machine.Pin(13, machine.Pin.OUT)
# YELLOW1 = machine.Pin(12, machine.Pin.OUT)
# GREEN1 = machine.Pin(11, machine.Pin.OUT)
 
# Traffic signal pins
SN_SIGNAL_RED = machine.Pin(18, machine.Pin.OUT)
SN_SIGNAL_YELLOW = machine.Pin(19, machine.Pin.OUT)
SN_SIGNAL_GREEN = machine.Pin(20, machine.Pin.OUT)
 
# NOTE: IT sensors are active low, which means they send a HIGH (1) when there is no obstruction and a LOW (0) when there is an obstruction.
# Ped Xing IR Pin
SN_PEDXING_IR = machine.Pin(17, machine.Pin.IN) #active low
# Number of cars IR Pin
SN_NUMCARS_IR = machine.Pin(15, machine.Pin.IN) #active low
# Ped Xing Push button
SN_PEDXING_BUTTON = machine.Pin(21, machine.Pin.IN , machine.Pin.PULL_DOWN)    #pulled down so that value turns 1 when button pressed
 
# END CHANGE BY STEMVentor
 
# START CHANGE BY STEMVentor
 
# For East-West traffic flow signal (see note on circuit diagram)
 
# RED2 = machine.Pin(9, machine.Pin.OUT)
# YELLOW2 = machine.Pin(8, machine.Pin.OUT)
# GREEN2 = machine.Pin(7, machine.Pin.OUT)
 
# Traffic signal pins
EW_SIGNAL_RED = machine.Pin(6, machine.Pin.OUT)
EW_SIGNAL_YELLOW = machine.Pin(7, machine.Pin.OUT)
EW_SIGNAL_GREEN = machine.Pin(8, machine.Pin.OUT)
 
# Ped Xing IR Pin
EW_PEDXING_IR = machine.Pin(14, machine.Pin.IN) #active low
# Number of cars IR Pin
EW_NUMCARS_IR = machine.Pin(16, machine.Pin.IN) #active low
# END CHANGE BY STEMVentor
# Ped Xing Push button
EW_PEDXING_BUTTON = machine.Pin(13, machine.Pin.IN , machine.Pin.PULL_DOWN)    #pulled down so that value turns 1 when button pressed
 
# END CHANGE BY STEMVentor
 
# START CHANGE BY STEMVentor
 
# TO CHECK CROSSING 2
# IR2 = machine.Pin(6, machine.Pin.IN)                     #active low
# TO CHECK CROSSING 1
# IR1 = machine.Pin(10, machine.Pin.IN)                    #active low
# TO CHECK FOR MULTIPLE CARS IN NORTH SOUTH LANE
# IRS = machine.Pin(5, machine.Pin.IN)                     #active low
# TO CHECK FOR MULTIPLE CARS IN EAST WEST LANE
# IRE = machine.Pin(4, machine.Pin.IN)                     #active low
 
# FOR CROSSING ON 1
# push1 = machine.Pin(3, machine.Pin.IN , machine.Pin.PULL_DOWN)    #pulled down so that value turns 1 when button pressed
# FOR CROSSING ON 2
# push2 = machine.Pin(2, machine.Pin.IN , machine.Pin.PULL_DOWN)    #pulled down so that value turns 1 when button pressed
 
# END CHANGE BY STEMVentor
 
# to store IR values
# IRV1 = 0
# IRV2 = 0
# IRSV = 0
# IREV = 0
 
#-------------Variables------------#
# Time to switch between signals in seconds
NORMAL_DELAY = 5
PEDXING_DELAY = 10
HEAVY_TRAFFIC_DELAY = 15
# Time to add if other ped xing has been pressed
PEDXING_TIME = 4
 
# Initialize IR sensor and push button values
SN_PEDXING_IR_VALUE = 0
SN_NUMCARS_IR_VALUE = 0
EW_PEDXING_IR_VALUE = 0
EW_NUMCARS_IR_VALUE = 0
 
# To store push button values
# pushV1 = 0
# pushV2 = 0
SN_PEDXING_BUTTON_VALUE = 0
EW_PEDXING_BUTTON_VALUE = 0
 
# Variables to store signal status
# sig1 = False
# sig2 = False
SN_SIGNAL_ON = False
EW_SIGNAL_ON = False
 
#-------various functions-----------#
 
# This function will turn the traffic light passed to green and the other to red.
# It is assumed that the other light is green so first take it to red.
# Both will go through yellow.
# The delay will be decided based on the inputs:
# If a ped xing is requested a a signal it will turn red with a shorter delay.
# If there is heavier traffic detected by the number of cars IR sensor it will turn red with a longer delay
# If there are no such inputs it will turn red with a normal delay
def switchTrafficSignalGreen(traffic_signal_id, delay):
    global SN_SIGNAL_ON, EW_SIGNAL_ON
    
    time.sleep(delay)
    
    if traffic_signal_id == 'SN_SIGNAL':
        # First take the other signal to red.
        EW_SIGNAL_GREEN.value(0)
        EW_SIGNAL_YELLOW.value(1)
        time.sleep(1)
        EW_SIGNAL_YELLOW.value(0)
        EW_SIGNAL_RED.value(1)
        # Then this one to green.
        SN_SIGNAL_RED.value(0)
        SN_SIGNAL_YELLOW.value(1)
        time.sleep(1)
        SN_SIGNAL_YELLOW.value(0)
        SN_SIGNAL_GREEN.value(1)
        # Set the signal values to on and off
        SN_SIGNAL_ON = True
        EW_SIGNAL_ON = False
        
    elif traffic_signal_id == 'EW_SIGNAL':
        # First take the other signal to red.
        SN_SIGNAL_GREEN.value(0)
        SN_SIGNAL_YELLOW.value(1)
        time.sleep(1)
        SN_SIGNAL_YELLOW.value(0)
        SN_SIGNAL_RED.value(1)
        # Then this one to green.
        EW_SIGNAL_RED.value(0)
        EW_SIGNAL_YELLOW.value(1)
        time.sleep(1)
        EW_SIGNAL_YELLOW.value(0)
        EW_SIGNAL_GREEN.value(1)
        # Set the signal values to on and off
        SN_SIGNAL_ON = False
        EW_SIGNAL_ON = True
 
# Function to turn signal 1 on, signal 2 off
def case1():
    # global IRV2, sig1, sig2, IRSV
    global SN_PEDXING_IR_VALUE, SN_NUMCARS_IR_VALUE, SN_SIGNAL_ON, EW_SIGNAL_ON
    while IRV2 == 0:   # to check if any object/pedistrian on that particular crossing before turning that signal green
        emg2()         # if pedistrian is there then emg2 execute. 
        IRV2 = IR2.value()
    
#     print("signal 2 was on and will become off, signal 1 was off and will turn on")
#     GREEN2.value(0)
#     YELLOW2.value(1)
#     time.sleep(1)
#     YELLOW2.value(0)
#     RED2.value(1)
#     RED1.value(0)
#     YELLOW1.value(1)
#     time.sleep(1)
#     YELLOW1.value(0)
#     GREEN1.value(1)
    
    # Turn SN Signal Green
    print("Turning SN signal green and EW signal red.")
    switchTrafficSignalGreen('SN_SIGNAL')
    
    if IRSV == 0 :
        print("Mulpitple cars in north south lane")
        time.sleep(4)
    sig2 = False
    sig1 = True
 
def case2(): # function to make signal 1 off, signal 2 on
    global IRV1, sig1, sig2, IREV
    while IRV1 == 0:   # to check if any object/pedistrian on that particular crossing before turning that signal green
        emg1()         # if pedistrian is there then emg1 execute.
        IRV1 = IR1.value()
    print("signal 1 was on and will become off, signal 2 was off and will turn on")
    GREEN1.value(0)
    YELLOW1.value(1)
    time.sleep(1)
    YELLOW1.value(0)
    RED1.value(1)
    RED2.value(0)
    YELLOW2.value(1)
    time.sleep(1)
    YELLOW2.value(0)
    GREEN2.value(1)
    if IREV == 0 :
        print("Mulpitple cars in east west lane")
        time.sleep(4)
    sig2 = True
    sig1 = False
 
def ped2(): #function for pedstrian to cross on crossing number 2
    print("pedistrian on crossing 2 is crossing")
    if sig1: #if signal N-S on then make it red and wait for 7 sec
        case2()
        time.sleep(7)
    elif sig2: #if signal N-S off then simply wait for 7 sec
        time.sleep(7)
 
def ped1():  #function for pedstrian to cross on crossing number 1
    print("pedistrian on crossing 1 is crossing")
    if sig2: #if signal E-W on then make it red and wait for 7 sec
        case1()
        time.sleep(7)
    elif sig1: #if signal E-W off then simply wait for 7 sec
        time.sleep(7)
 
def emg1():  #Function if object detected on crossing 1 then make E-W signal red 
    print("EMG 1 EXECUTING")
    RED2.value(1)
    YELLOW2.value(0)
    GREEN2.value(0)
    time.sleep(1)
 
def emg2(): #Function if object detected on crossing 2 then make N-S signal red 
    print("EMG 2 EXECUTING")
    RED1.value(1)
    YELLOW1.value(0)
    GREEN1.value(0)
    time.sleep(1)    
 
# Main loop like in an Arduino sketch
def loop(): 
#     global IRV1, IRV2, IRSV, IREV, pushV1, pushV2, sig1, sig2
#     time.sleep(2)
#     #read all IR sensors value and push button value
#     IRV1 = IR1.value()
#     IRV2 = IR2.value()
#     IRSV = IRS.value()
#     IREV = IRE.value()
#     pushV1 = push1.value()
#     pushV2 = push2.value()
    
    global  SN_PEDXING_IR_VALUE, SN_NUMCARS_IR_VALUE, \
    EW_PEDXING_IR_VALUE, EW_NUMCARS_IR_VALUE, \
    SN_PEDXING_BUTTON_VALUE, EW_PEDXING_BUTTON_VALUE, \
    SN_SIGNAL_ON, EW_SIGNAL_ON, \
    DEFAULT_SIGNAL_TIME, PEDXING_TIME
 
 
    # Read all IR sensor values.
    # Note that IR sensors are active low but when reading the value is reversed to make logical conditions used later meaningful.
    SN_PEDXING_IR_VALUE = not SN_PEDXING_IR.value()
    SN_NUMCARS_IR_VALUE = not SN_NUMCARS_IR.value()
    EW_PEDXING_IR_VALUE = not EW_PEDXING_IR.value()
    EW_NUMCARS_IR_VALUE = not EW_NUMCARS_IR.value()
    
    # Read pushbutton values.
    SN_PEDXING_BUTTON_VALUE = SN_PEDXING_BUTTON.value()
    EW_PEDXING_BUTTON_VALUE = EW_PEDXING_BUTTON.value()
    
#     print("SN_PEDXING_IR_VALUE:", SN_PEDXING_IR_VALUE,
#           "SN_NUMCARS_IR_VALUE:", SN_NUMCARS_IR_VALUE,
#           "EW_PEDXING_IR_VALUE:", EW_PEDXING_IR_VALUE,
#           "EW_NUMCARS_IR_VALUE:", EW_NUMCARS_IR_VALUE,
#           "SN_PEDXING_BUTTON_VALUE:", SN_PEDXING_BUTTON_VALUE,
#           "EW_PEDXING_BUTTON_VALUE:", EW_PEDXING_BUTTON_VALUE,
#           "SN_SIGNAL_ON:", SN_SIGNAL_ON,
#           "EW_SIGNAL_ON:", EW_SIGNAL_ON)
    
    
#     if pushV1:  #for pedistrian on crossing 1 
#         ped1()
# 
#     if pushV2:  #for pedistrian on crossing 2
#         ped2()
# 
#     if sig1:    #if N-S signal on then make it red for 4 sec
#         case2()
#         time.sleep(4)
# 
#     elif sig2:  #if E-W signal on then make it red for 4 sec
#         case1()
#         time.sleep(4)
# 
#     else:       #will execute on when the microcontroller starts   
#         case1()
#         time.sleep(4)
#         case2()
#         time.sleep(4)
 
    print("SN_SIGNAL_ON:", SN_SIGNAL_ON);
    print("EW_SIGNAL_ON:", EW_SIGNAL_ON);
    
    # If there is anything on the ped xing (a person crossing or a car stopped on the ped xing)
    # the other signal should stay red if already red. So if the NS_PEDXING_IR is true keep EW_SIGNAL on and vice versa.
    # But if green cars will be passing so cannot turn it red.
    if SN_PEDXING_IR_VALUE:
        switchTrafficSignalGreen('SN_SIGNAL', NORMAL_DELAY)
        
    elif EW_PEDXING_IR_VALUE:
        switchTrafficSignalGreen('EW_SIGNAL', NORMAL_DELAY)
 
    # Ped xing gets priority followed by heavy traffic.
    # If SN signal is green and ped xing requested on SN signal only turn SN signal red and EW signal green with a shorter delay .
    # Note that IR sensors are active low but whn reading the value is reversed in code to make the conditions below meaningful.
    # elif SN_SIGNAL_ON and (SN_PEDXING_IR_VALUE or SN_PEDXING_BUTTON_VALUE) and not EW_PEDXING_IR_VALUE and not EW_PEDXING_BUTTON_VALUE:
    elif SN_SIGNAL_ON and SN_PEDXING_BUTTON_VALUE and not EW_PEDXING_BUTTON_VALUE:
        switchTrafficSignalGreen('SN_SIGNAL', PEDXING_DELAY)
    
    # If EW signal is green ped xing requested on EW signal only turn EW signal red and SN signal green with a shorter delay.
    # elif EW_SIGNAL_ON and (EW_PEDXING_IR_VALUE or EW_PEDXING_BUTTON_VALUE) and not SN_PEDXING_IR_VALUE and not SN_PEDXING_BUTTON_VALUE:
    elif EW_SIGNAL_ON and EW_PEDXING_BUTTON_VALUE and not SN_PEDXING_BUTTON_VALUE: 
        switchTrafficSignalGreen('EW_SIGNAL', PEDXING_DELAY)
        
    # If heavy traffic on SN signal turn EW signal green with a higher delay
    elif SN_SIGNAL_ON and SN_NUMCARS_IR_VALUE:
        print("SN_NUMCARS_IR_VALUE:", SN_NUMCARS_IR_VALUE)
        switchTrafficSignalGreen('EW_SIGNAL', HEAVY_TRAFFIC_DELAY)
    
    # If heavy traffic on EW signal turn SN signal green with a higher delay
    elif EW_SIGNAL_ON and EW_NUMCARS_IR_VALUE:
        print("EW_NUMCARS_IR_VALUE:", EW_NUMCARS_IR_VALUE)
        switchTrafficSignalGreen('SN_SIGNAL', HEAVY_TRAFFIC_DELAY)
        
    # If ped xing requested on both signals or no ped xing requested and no heavy traffic.
    # follow normal delay 
    else:
        if (not SN_SIGNAL_ON and not EW_SIGNAL_ON):
            print("Just starting")
            switchTrafficSignalGreen('SN_SIGNAL', NORMAL_DELAY) 
        elif SN_SIGNAL_ON:
            switchTrafficSignalGreen('EW_SIGNAL', NORMAL_DELAY)
        elif EW_SIGNAL_ON:
            switchTrafficSignalGreen('SN_SIGNAL', NORMAL_DELAY) 
        
# To make the loop run continuously  
while True:     
    loop()