7.2. LED Traffic Light

In this project we will use 3 LEDs to simulate normal traffic light operation. Pushbutton is added to represent catwalk interrupt button which stops the normal operation of the traffic light to allow "pedestrians" to cross over.
At the end of this example you will learn:
- How to use LEDs in a sequence
- How to trigger a hardware based interrupt
- How to attach a timer interrupt in
TIMER.ONE_SHOTmode
Parts required:
- Soldered NULA Mini Board
- Breadboard
- 1 x Red, Green, Yellow LED
- 3 x 330Ω resistors
- 1 x Pushbutton
- Some jumper wires

Code Example
Import necessary modules.
# Import necessary modules
from machine import Pin, Timer
import time
Define pins used for LEDs.
RED_LED_PIN = 5
YELLOW_LED_PIN = 4
GREEN_LED_PIN = 3
Global variables which control the state of the program flow when a certain action occurs.
request_red = False
green_light_on = False
button_timeout_expired = True
last_button_press = 0
Create a timer by calling Timer() constructor with given id.
timeout_timer = Timer(0)
Pushbutton interrupt handler routine, sets the global request_red variable to True and updates the last_button_press time. This will only be executed if green light is currently ON and timeout for catwalk button has expired.
def irq_handler(pin):
if green_light_on and button_timeout_expired:
global request_red, last_button_press
# Debounce catwalk button
if time.ticks_diff(time.ticks_ms(), last_button_press) >= 500:
last_button_press = time.ticks_ms()
print("Catwalk button pressed!")
request_red = True
Here we define functions to when green light turns off, function green_off_sequence() turns of the green LED after blinking it for few times followed by turning on the yellow LED.
def blink_green():
for _ in range(4):
green_led.value(0)
time.sleep(0.5)
green_led.value(1)
time.sleep(0.5)
def green_off_sequence():
global green_light_on
green_light_on = False
blink_green()
green_led.value(0)
yellow_led.value(1)
time.sleep(3)
yellow_led.value(0)
Timer handler which triggers 25 seconds after each pushbutton press, during that time catwalk button is disabled to ensure some time between repeated presses.
def timeout_handler(t):
global button_timeout_expired
button_timeout_expired = True
print("Button timeout expired, can request red light again.")
Define pin for pushbutton and initialize the Pin object. After button initialization attach an interrupt to trigger on press.
BUTTON_PIN = 18
catwalk_button = Pin(BUTTON_PIN, Pin.IN, Pin.PULL_UP)
catwalk_button.irq(trigger=Pin.IRQ_FALLING, handler=irq_handler)
Define and initialize the LEDs and turn them all off initially.
red_led = Pin(RED_LED_PIN, Pin.OUT)
yellow_led = Pin(YELLOW_LED_PIN, Pin.OUT)
green_led = Pin(GREEN_LED_PIN, Pin.OUT)
red_led.value(0)
yellow_led.value(0)
green_led.value(0)
Main loop that starts off by turning on the red LED, followed by yellow and green. Green LED stays on the longest for 10 seconds after which green_off_sequence() begins. While the green LED is on, pushbutton can trigger an interrupt to immediately start the process of turning the green LED off and turning on the red LED.
while True:
red_led.value(1) # Turn on red LED
time.sleep(5) # Wait for 10 seconds
yellow_led.value(1) # Turn on yellow LED
time.sleep(3) # Wait for 3 seconds
red_led.value(0) # Turn off red LED
yellow_led.value(0) # Turn off yellow LED
green_led.value(1) # Turn on green LED
# Save the time green light started
green_light_start = time.ticks_ms()
while True:
green_light_on = True
# If 10 seconds passed, end green light
if time.ticks_diff(time.ticks_ms(), green_light_start) > 10000:
# Begin green light off sequence and exit the loop
green_off_sequence()
break
# If pushbutton interrupt timeout expired allow the interrupt to happen
if button_timeout_expired:
if request_red == True:
green_off_sequence()
# Reset the flag
request_red = False
button_timeout_expired = False
# Start a 'ONE_SHOT' timer which will trigger only once after 25 seconds
timeout_timer.init(period=25000, mode=Timer.ONE_SHOT, callback=timeout_handler)
break