import time
from machine import Pin
############################################################################################################
## GPIO input and outputs
# define which pins are used for each Led on board and set pins to output mode
led_red_1 = Pin(14,Pin.OUT)
led_yellow_1 = Pin(13,Pin.OUT)
led_green_1 = Pin(12,Pin.OUT)
led_red_2 = Pin(17,Pin.OUT)
led_yellow_2 = Pin(18,Pin.OUT)
led_green_2 = Pin(19,Pin.OUT)
emergency_led = Pin(11,Pin.OUT)
reset_led = Pin(10,Pin.OUT)
pedestrian_led_1 = Pin(21,Pin.OUT)
pedestrian_led_2 = Pin(22,Pin.OUT)
#Define push buttons and buzzer and the pins they are attached to, Buttons are set in Pull down mode
#so default state is low
push_button_blue = Pin(16,Pin.IN,Pin.PULL_DOWN)
push_button_green = Pin(15,Pin.IN,Pin.PULL_DOWN)
push_button_white = Pin(7,Pin.IN,Pin.PULL_DOWN)
push_button_yellow = Pin(8,Pin.IN,Pin.PULL_DOWN)
buzzer = Pin(20,Pin.OUT)
#define 7 segment displays, pin values are set high so all led segments are initailly off
top_segment_A = Pin(5,Pin.OUT,value=1)
top_right_segment_B = Pin(6,Pin.OUT,value=1)
top_left_segment_F = Pin(4,Pin.OUT,value=1)
middle_segment_G = Pin(3,Pin.OUT,value=1)
bottom_right_segment_C = Pin(0,Pin.OUT,value=1)
bottom_left_segment_E = Pin(2,Pin.OUT,value=1)
bottom_segment_D = Pin(1,Pin.OUT,value=1)
##define binary output pins for ic 4511 if using to drive 7 segment display
#binary_output_1 = machine.Pin(0,Pin.OUT)
#binary_output_2 = machine.Pin(1,Pin.OUT)
#binary_output_3 = machine.Pin(2,Pin.OUT)
#binary_output_4 = machine.Pin(3,Pin.OUT)
###########################################################################################################
###########################################################################################################
## VARIABLES
##Define varaibles to keep track of the current state of the traffic lights and if pedestrian button has been pressed
#previous_state = None
current_state = 'RED_1'
pedestrian = None
## add interupt priority levels so that pedsterain and reset buttons cant interrupt emergency button
#priority_level = 0
# varibale to control time green lights and red lights stay on
red_light_time = 10
green_light_1_time = 10
green_light_2_time = 10
###########################################################################################################
###########################################################################################################
## FUNCTIONS
def LED_ON_SEQUENCE(R_1,Y_1,G_1,R_2,Y_2,G_2,TIME):
led_red_1.value(R_1)
led_yellow_1.value(Y_1)
led_green_1.value(G_1)
led_red_2.value(R_2)
led_yellow_2.value(Y_2)
led_green_2.value(G_2)
time.sleep(TIME)
def RESET_button(Pin):
push_button_yellow.irq(handler=None) # set interupt handler to none so that the switch bounce doesn't trigger multiple times
reset_led.value(1)
global current_state
current_state = 'RED_1'
if led_red_1.value() == 1 and led_red_2.value() == 1:
LED_ON_SEQUENCE(1,0,0,1,0,0,5)
elif led_red_1.value() != 1:
LED_ON_SEQUENCE(0,1,0,1,0,0,1)
LED_ON_SEQUENCE(1,0,0,1,0,0,5)
elif led_red_2.value != 1:
LED_ON_SEQUENCE(1,0,0,0,1,0,1)
LED_ON_SEQUENCE(1,0,0,1,0,0,5)
push_button_yellow.irq(trigger=Pin.IRQ_RISING, handler=RESET_button) # re-initilase trigger handler so button will trigger when pushed
reset_led.value(0)
def EMERGENCY_button(Pin):
push_button_white.irq(handler=None)
push_button_yellow.irq(handler=None)
emergency_led.value(1)
global current_state
pressed = True
if led_red_1.value() == 1 and led_red_2.value() == 1:
LED_ON_SEQUENCE(1,0,0,1,0,0,1)
elif led_red_1.value() != 1:
LED_ON_SEQUENCE(0,1,0,1,0,0,1)
LED_ON_SEQUENCE(1,0,0,1,0,0,1)
else:
LED_ON_SEQUENCE(1,0,0,0,1,0,1)
LED_ON_SEQUENCE(1,0,0,1,0,0,1)
while pressed:
if push_button_white.value() == 1:
pressed = False
emergency_led.value(0)
time.sleep(0.2)
time.sleep(0.2)
if '1' in current_state:
current_state = 'RED_2' # check prev state to choose RED_1 or RED_2
elif '2' in current_state:
current_state ='RED_1'
push_button_white.irq(trigger=Pin.IRQ_RISING, handler=EMERGENCY_button)
push_button_yellow.irq(trigger=Pin.IRQ_RISING, handler=RESET_button)
#use this function if driving a 7 segment display directly from microcontroller pins
def crossing_sequence_1():
#segment order = [top,top left,top right, middle, bottom left, bottom right, bottom] digits =[5,4,3,2,1,0,off]
digits =['0010100','1000101','0100100','0100010','1101101','0001000','1111111']
for i in range(8):
buzzer.value(1)
time.sleep(0.2)
buzzer.value(0)
time.sleep(0.2)
for number in digits:
top_segment_A.value(int(number[0]))
top_left_segment_F.value(int(number[1]))
top_right_segment_B.value(int(number[2]))
middle_segment_G.value(int(number[3]))
bottom_left_segment_E.value(int(number[4]))
bottom_right_segment_C.value(int(number[5]))
bottom_segment_D.value(int(number[6]))
for i in range(4):
buzzer.value(1)
time.sleep(0.2)
buzzer.value(0)
time.sleep(0.2)
time.sleep(1)
#use this function if using a 4511 chip to drive 7 segment displays
def crossing_sequence_2():
#digits = binary output for digits 0-9 in descending order
digits =['1001','1000','0111','0110','0101','0100','0011','0010','0001','0000']
for i in range(2):
buzzer.value(1)
time.sleep(0.5)
buzzer.value(0)
time.sleep(0.5)
for digit in digits:
binary_output_1.value(int(digit[0]))
binary_output_2.value(int(digit[1]))
binary_output_3.value(int(digit[2]))
binary_output_4.value(int(digit[3]))
buzzer.value(1)
time.sleep(0.5)
buzzer.value(0)
time.sleep(0.5)
time.sleep(1)
def pedestrian_button_pressed(Pin):
push_button_green.irq(handler=None)
push_button_blue.irq(handler=None)
pedestrian_led_1.value(1)
pedestrian_led_2.value(1)
global pedestrian
pedestrian = 'PEDESTRIAN'
time.sleep(0.2)
#maybe move line 132,133 to main while loop after crossing_sequence so button cant be pressed during sequence
###########################################################################################################
# interupt pins set to trigger on the risng edge of the button push
push_button_white.irq(trigger=Pin.IRQ_RISING, handler=EMERGENCY_button)
push_button_yellow.irq(trigger=Pin.IRQ_RISING, handler=RESET_button)
push_button_blue.irq(trigger=Pin.IRQ_RISING,handler=pedestrian_button_pressed)
push_button_green.irq(trigger=Pin.IRQ_RISING,handler=pedestrian_button_pressed)
while True:
if pedestrian == 'PEDESTRIAN':
if current_state == 'RED_1':
current_state = 'RED_AMBER_1'
pedestrian = None
LED_ON_SEQUENCE(1,0,0,1,0,0,1)
crossing_sequence_1()
pedestrian_led_1.value(0)
pedestrian_led_2.value(0)
push_button_green.irq(trigger=Pin.IRQ_RISING,handler=pedestrian_button_pressed)
push_button_blue.irq(trigger=Pin.IRQ_RISING,handler=pedestrian_button_pressed)
elif current_state == 'RED_2':
current_state = 'RED_AMBER_2'
pedestrian = None
LED_ON_SEQUENCE(1,0,0,1,0,0,1)
crossing_sequence_1()
pedestrian_led_1.value(0)
pedestrian_led_2.value(0)
push_button_green.irq(trigger=Pin.IRQ_RISING,handler=pedestrian_button_pressed)
push_button_blue.irq(trigger=Pin.IRQ_RISING,handler=pedestrian_button_pressed)
if current_state == 'RED_1':
current_state='RED_AMBER_1'
LED_ON_SEQUENCE(1,0,0,1,0,0,red_light_time)
elif current_state == 'RED_AMBER_1':
current_state = 'GREEN_1'
LED_ON_SEQUENCE(1,1,0,1,0,0,2)
elif current_state == 'GREEN_1':
current_state = 'AMBER_1'
LED_ON_SEQUENCE(0,0,1,1,0,0,green_light_1_time)
elif current_state == 'AMBER_1':
current_state = 'RED_2'
LED_ON_SEQUENCE(0,1,0,1,0,0,2)
elif current_state == 'RED_2':
current_state = 'RED_AMBER_2'
LED_ON_SEQUENCE(1,0,0,1,0,0,red_light_time)
elif current_state == 'RED_AMBER_2':
current_state = 'GREEN_2'
LED_ON_SEQUENCE(1,0,0,1,1,0,2)
elif current_state == 'GREEN_2':
current_state = 'AMBER_2'
LED_ON_SEQUENCE(1,0,0,0,0,1,green_light_2_time)
elif current_state == 'AMBER_2':
current_state = 'RED_1'
LED_ON_SEQUENCE(1,0,0,0,1,0,2)