Objective:
Understand a MicroPython system that controls a set of traffic lights using buttons and timers.
Components:
Additional Notes:
Program Structure:
Initialization
|
|
V
Mode Switch
/ \
/ \
Auto Mode Manual Mode
| |
| | |
V V
Switch Light Check Button
Note: The blue button toggles between the auto and manual modes.
Button Debounce with Timer and IRQ Flag
from machine import Pin, Timer
import utime
color_and_pin_list = [('red', 23), ('yellow', 22), ('green', 21)]
leds = {color: Pin(pin, Pin.OUT) for color, pin in color_and_pin_list}
button_and_pin_list = [('red_b', 32), ('yellow_b', 33), ('green_b', 25), ('blue_b', 4)]
buttons = {color: Pin(pin, Pin.IN, Pin.PULL_UP) for color, pin in button_and_pin_list}
auto_mode = True
machine
and utime
are imported.auto_mode
determines the operating mode.def change_light(t):
if leds['red'].value():
leds['red'].off()
leds['green'].on()
auto_mode_timer.init(period=700, mode=Timer.ONE_SHOT, callback=change_light)
elif leds['green'].value():
leds['green'].off()
leds['yellow'].on()
auto_mode_timer.init(period=200, mode=Timer.ONE_SHOT, callback=change_light)
else:
leds['yellow'].off()
leds['red'].on()
auto_mode_timer.init(period=500, mode=Timer.ONE_SHOT, callback=change_light)
auto_mode_timer = Timer(0)
leds['green'].on()
auto_mode_timer.init(period=700, mode=Timer.ONE_SHOT, callback=change_light)
change_light
controls the sequence of traffic light changes.auto_mode_timer
periodically calls this function.def check_buttons(t):
if not buttons['red_b'].value():
leds['red'].on()
leds['yellow'].off()
leds['green'].off()
elif not buttons['yellow_b'].value():
leds['red'].off()
leds['yellow'].on()
leds['green'].off()
elif not buttons['green_b'].value():
leds['red'].off()
leds['yellow'].off()
leds['green'].on()
button_check_timer = Timer(1)
#button_check_timer.init(period=50, mode=Timer.PERIODIC, callback=check_buttons)
check_buttons
checks if any button is pressed and adjusts the LED state accordingly.button_check_timer
is prepared to check button presses periodically in manual mode.def toggle_auto_mode(pin):
global auto_mode, irq_isenable
if irq_isenable:
auto_mode = not auto_mode
irq_isenable = False
Timer(-1).init(mode=Timer.ONE_SHOT, period=200, callback=enable_irq)
if auto_mode:
button_check_timer.deinit()
auto_mode_timer.init(period=700, mode=Timer.ONE_SHOT, callback=change_light)
else:
auto_mode_timer.deinit()
button_check_timer.init(period=50, mode=Timer.PERIODIC, callback=check_buttons)
print("自動模式:", auto_mode)
blue_button = buttons['blue_b']
blue_button.irq(trigger=Pin.IRQ_FALLING, handler=toggle_auto_mode)
toggle_auto_mode
function switches between automatic and manual modes.print("自動模式:", auto_mode)
while True:
utime.sleep_ms(50)
Button Debounce with Time Tick Difference
from machine import Pin, Timer
import utime
color_and_pin_list = [('red', 23), ('yellow', 22), ('green', 21)]
leds = {color: Pin(pin, Pin.OUT) for color, pin in color_and_pin_list}
button_and_pin_list = [('red_b', 32), ('yellow_b', 33), ('green_b', 25), ('blue_b', 4)]
buttons = {color: Pin(pin, Pin.IN, Pin.PULL_UP) for color, pin in button_and_pin_list}
def change_light(t):
if leds['red'].value():
leds['red'].off()
leds['green'].on()
auto_mode_timer.init(period=700, mode=Timer.ONE_SHOT, callback=change_light)
elif leds['green'].value():
leds['green'].off()
leds['yellow'].on()
auto_mode_timer.init(period=200, mode=Timer.ONE_SHOT, callback=change_light)
else:
leds['yellow'].off()
leds['red'].on()
auto_mode_timer.init(period=500, mode=Timer.ONE_SHOT, callback=change_light)
change_light
function manages the LED transitions based on their current state.def check_buttons(t):
if not buttons['red_b'].value():
leds['red'].on()
leds['yellow'].off()
leds['green'].off()
elif not buttons['yellow_b'].value():
leds['red'].off()
leds['yellow'].on()
leds['green'].off()
elif not buttons['green_b'].value():
leds['red'].off()
leds['yellow'].off()
leds['green'].on()
check_buttons
function assesses which button has been pressed.auto_mode_timer = Timer(0)
leds['green'].on()
auto_mode_timer.init(period=700, mode=Timer.ONE_SHOT, callback=change_light)
button_check_timer = Timer(1)
auto_mode = True
debounce_time_ms = 150
last_button_press_time = 0
def toggle_auto_mode(pin):
global auto_mode, last_button_press_time
current_time = utime.ticks_ms()
press_time_diff = utime.ticks_diff(current_time, last_button_press_time)
if press_time_diff >= debounce_time_ms:
last_button_press_time = current_time
auto_mode = not auto_mode
if auto_mode:
button_check_timer.deinit()
auto_mode_timer.init(period=700, mode=Timer.ONE_SHOT, callback=change_light)
else:
auto_mode_timer.deinit()
button_check_timer.init(period=50, mode=Timer.PERIODIC, callback=check_buttons)
print("自動模式:", auto_mode)
blue_button = buttons['blue_b']
blue_button.irq(trigger=Pin.IRQ_FALLING, handler=toggle_auto_mode)
toggle_auto_mode
function switches modes using the blue button.print("自動模式:", auto_mode)
while True:
utime.sleep_ms(50)