from machine import I2C, Pin, Timer
import time
from pico_i2c_lcd import I2cLcd
# 初始化 I2C 通信
i2c = I2C(0, sda=Pin(0), scl=Pin(1), freq=400000)
# 初始化 LCD 顯示器
lcd = I2cLcd(i2c, 0x27, 2, 16)
# 定義每個 LED 的顏色和腳位
led1 = {'r': Pin(3, Pin.OUT), 'y': Pin(4, Pin.OUT), 'g': Pin(5, Pin.OUT)}
led2 = {'r': Pin(10, Pin.OUT), 'y': Pin(11, Pin.OUT), 'g': Pin(12, Pin.OUT)}
# 定義按鈕的腳位
btn_mode = Pin(21, Pin.IN, Pin.PULL_DOWN)
btn_flip = Pin(16, Pin.IN, Pin.PULL_DOWN)
# 定義交通燈模式
MODES = {0: "Flash Red", 1: "Flash Yellow", 2: "Alt Flash R-Y", 3: "Alt Flash Y-R", 4: "Seq", 5: "Manual"}
# 設置當前模式
mode = 0
manual_flip = False # 標誌手動控制的方向
flipping = False # 標誌是否正在進行方向切換
step = 0 # 初始化常规交通灯序列的步骤
# 去抖動延遲
debounce = 200 # 毫秒
# 初始化時間記錄
last_mode_time = 0
last_flip_time = 0
# 初始化閃爍狀態
flash = False
# 關閉所有LED燈
def all_off():
for color in led1:
led1[color].value(0)
led2[color].value(0)
# 更新 LCD 顯示
def update_lcd():
lcd.clear()
lcd.putstr(f"Mode: {mode}")
if mode == 5:
lcd.move_to(0, 1)
lcd.putstr("Dir: B St. Go" if manual_flip else "Dir: A St. Go")
# 控制交通燈狀態的函數
def ctrl_lights(timer):
global mode, flash, manual_flip, step
flash = not flash # 切換閃爍狀態
all_off() # 先關閉所有燈
if mode == 0: # 閃爍紅燈
led1['r'].value(flash)
led2['r'].value(flash)
elif mode == 1: # 閃爍黃燈
led1['y'].value(flash)
led2['y'].value(flash)
elif mode == 2: # 交替閃爍紅黃
led1['r'].value(flash)
led2['y'].value(flash)
elif mode == 3: # 交替閃爍黃紅
led1['y'].value(flash)
led2['r'].value(flash)
elif mode == 4: # 常規交通燈序列
if step == 0: # 第一步:第一組紅燈,第二組綠燈 (R/G)
led1['r'].value(1)
led2['g'].value(1)
elif step == 1: # 第二步:第一組紅燈,第二組黃燈 (R/Y)
led1['r'].value(1)
led2['y'].value(1)
elif step == 2: # 第三步:第一組綠燈,第二組紅燈 (G/R)
led1['g'].value(1)
led2['r'].value(1)
elif step == 3: # 第四步:第一組黃燈,第二組紅燈 (Y/R)
led1['y'].value(1)
led2['r'].value(1)
step = (step + 1) % 4
elif mode == 5: # 手動控制方向切換
if manual_flip: # 第一組綠燈, 第二組紅燈
led1['g'].value(1)
led2['r'].value(1)
else: # 第一組紅燈, 第二組綠燈
led1['r'].value(1)
led2['g'].value(1)
# 處理模式切換的函數
def mode_btn(pin):
global mode, last_mode_time, step
if time.ticks_ms() - last_mode_time > debounce:
mode = (mode + 1) % len(MODES)
last_mode_time = time.ticks_ms()
update_lcd()
step = 0
# 處理方向切換的函數
def flip_btn(pin):
global manual_flip, last_flip_time, flipping
if time.ticks_ms() - last_flip_time > debounce and not flipping:
flipping = True
def transition():
global flipping, manual_flip
if manual_flip: # 目前是第一組綠燈, 第二組紅燈
led1['g'].value(0) # 綠燈熄滅
led1['y'].value(1) # 黃燈亮
led2['r'].value(1) # 第二組保持紅燈
time.sleep(1) # 保持黃燈一段時間(1秒)
led1['y'].value(0) # 黃燈熄滅
led1['r'].value(1) # 黃燈變紅燈
led2['r'].value(0) # 第二組的紅燈熄滅
led2['g'].value(1) # 第二組的紅燈變為綠燈
else: # 目前是第一組紅燈, 第二組綠燈
led2['g'].value(0) # 綠燈熄滅
led2['y'].value(1) # 黃燈亮
led1['r'].value(1) # 第一組保持紅燈
time.sleep(1) # 保持黃燈一段時間(1秒)
led2['y'].value(0) # 黃燈熄滅
led2['r'].value(1) # 黃燈變紅燈
led1['r'].value(0) # 第一組的紅燈熄滅
led1['g'].value(1) # 第一組的紅燈變為綠燈
manual_flip = not manual_flip
flipping = False
update_lcd() # 在手動控制完成後更新 LCD 顯示
transition()
last_flip_time = time.ticks_ms()
# 添加按鍵事件檢測
btn_mode.irq(trigger=Pin.IRQ_RISING, handler=mode_btn)
btn_flip.irq(trigger=Pin.IRQ_RISING, handler=flip_btn)
# 主程序
if __name__ == "__main__":
update_lcd()
# 創建定時器來執行控制交通燈狀態的函數
timer = Timer(-1)
timer.init(period=500, mode=Timer.PERIODIC, callback=ctrl_lights)
try:
while True:
pass
except KeyboardInterrupt:
pass
Loading
pi-pico-w
pi-pico-w