from machine import Pin, Timer

# Closs all the leds
def closs_all_led():
    leds['red'].off()
    leds['yellow'].off()
    leds['green'].off()

# Auto-light with setted period
# Sequence: red->yellow->green->yellow->red
def auto_traffic_lights(x=0):
    global current_state
    current_state = current_state % 3 + 1

    leds[states[current_state][0]].off()
    leds[states[current_state][1]].on()

    timer.init( period=period[states[current_state][1]],
                mode=Timer.ONE_SHOT,
                callback=auto_traffic_lights )

# Manual-light by press the buttom
def manual_traffic_lights(x=0):
    for color, pin in buttoms.items():
        if pin.value():
            closs_all_led()
            leds[color].on()

    timer.init( period=100,
                mode=Timer.ONE_SHOT,
                callback=manual_traffic_lights )

# Switch the mode to auto or manual
def interrupt_handler(x=0):
    global auto
    auto = not auto
    closs_all_led()

    if auto: auto_traffic_lights()
    else: manual_traffic_lights()

# Debouncing the switch buttom with unstable way
def debounce(x=0):
    timer.init( period=200, 
                mode=Timer.ONE_SHOT, 
                callback=interrupt_handler  )

timer = Timer(0)

# led set: red, yellow, green
led_pin_list = [('red', 13), ('yellow', 12), ('green', 14)]
leds = {color: Pin(pin, Pin.OUT) for color, pin in led_pin_list}

# buttom set: red, yellow, green
buttom_pin_list = [('red', 2), ('yellow', 4), ('green', 5)]
buttoms = {color: Pin(pin, Pin.IN, Pin.PULL_DOWN) for color, pin in buttom_pin_list}

# switch mode interrupt buttom: black
auto = True
switch = Pin(15, Pin.IN, Pin.PULL_DOWN)
switch.irq(trigger=Pin.IRQ_RISING, handler=debounce)

# states and period for every color of auto-light mode
current_state = 1
period = {'red': 500, 'yellow': 200, 'green': 700}
states = {  1: ('red', 'green'),
            2: ('green', 'yellow'),
            3: ('yellow', 'red')    }

# start with the auto-light mode
auto_traffic_lights()