交通灯
重要提示:关于开发板的兼容性
本教程的核心逻辑适用于所有 ESP32 开发板,但所有操作步骤均以 微雪 ESP32-S3-Zero 迷你开发板 为例进行讲解。如果您使用其他型号的开发板,请根据实际情况修改相应设置。
项目介绍
这个项目展示了一个交通灯的模拟程序,通过 ESP32 的 GPIO 引脚控制三个 LED 灯的亮灭,模拟交通灯的红、黄、绿灯切换过程。
硬件连接
需要使用的器件有:
- LED * 3
- 330Ω 电阻 * 3
- 面包板 * 1
- 导线
- ESP32 开发板
按照下面接线图连接电路:
ESP32-S3-Zero 引脚图


代码实现
import time
import machine
# 定义红、黄、绿灯分别连接的 GPIO 引脚号
RED_LED_PIN = 7
YELLOW_LED_PIN = 8
GREEN_LED_PIN = 9
# 定义红、绿、黄灯各自的持续时间
RED_LIGHT_DURATION = 10 # 红灯亮 10 秒
GREEN_LIGHT_DURATION = 8 # 绿灯亮 8 秒
YELLOW_LIGHT_DURATION = 3 # 黄灯阶段总共持续 3 秒
YELLOW_BLINK_INTERVAL = 0.5 # 黄灯闪烁间隔
# 初始化 LED 引脚为输出模式
red_led = machine.Pin(RED_LED_PIN, machine.Pin.OUT)
yellow_led = machine.Pin(YELLOW_LED_PIN, machine.Pin.OUT)
green_led = machine.Pin(GREEN_LED_PIN, machine.Pin.OUT)
def all_lights_off():
"""一个辅助函数,用于关闭所有灯。"""
red_led.off()
yellow_led.off()
green_led.off()
# 程序开始
print("交通灯模拟程序开始运行。..")
print(f"配置:红灯={RED_LIGHT_DURATION}s, 绿灯={GREEN_LIGHT_DURATION}s, 黄灯={YELLOW_LIGHT_DURATION}s")
print(f"黄灯闪烁间隔:{YELLOW_BLINK_INTERVAL}s")
try:
# 创建一个无限循环来模拟交通灯的持续工作
while True:
# --- 绿灯阶段 ---
print("绿灯亮")
all_lights_off() # 先关闭所有灯,确保状态干净
green_led.on() # 点亮绿灯
time.sleep(GREEN_LIGHT_DURATION) # 等待绿灯设定的时间
# --- 黄灯闪烁阶段 ---
print("黄灯闪烁")
green_led.off() # 熄灭绿灯
# 计算在指定的黄灯总时长内,应该闪烁多少次
# 一个完整的闪烁周期是 (亮 + 灭),时长为 YELLOW_BLINK_INTERVAL * 2
# 用总时长除以单个周期时长,得到闪烁次数
num_blinks = int(YELLOW_LIGHT_DURATION / (YELLOW_BLINK_INTERVAL * 2))
# 确保即使设置的总时间很短,也至少会闪烁一次
if num_blinks == 0:
num_blinks = 1
for _ in range(num_blinks):
yellow_led.on() # 点亮黄灯
time.sleep(YELLOW_BLINK_INTERVAL) # 亮一会
yellow_led.off() # 熄灭黄灯
time.sleep(YELLOW_BLINK_INTERVAL) # 灭一会
# 确保在进入红灯阶段前,黄灯是熄灭的
yellow_led.off()
# --- 红灯阶段 ---
print("红灯亮")
# 此时黄灯和绿灯已经熄灭,只需点亮红灯
red_led.on()
time.sleep(RED_LIGHT_DURATION) # 等待红灯设定的时间
except KeyboardInterrupt:
print("\n 程序被用户中断。")
finally:
# 无论程序是正常结束还是被中断,最后都确保所有灯都关闭
all_lights_off()
print("所有交通灯已关闭,程序结束。")
代码解释
-
导入库:
machine库用于控制硬件,time库用于实现延时。 -
常量定义:程序开头定义了 GPIO 引脚号(
RED_LED_PIN等)和各灯持续时间(RED_LIGHT_DURATION等)。将这些参数集中管理,便于后续根据实际需求快速调整,而无需深入修改逻辑代码。# 定义红、黄、绿灯分别连接的 GPIO 引脚号
RED_LED_PIN = 7
YELLOW_LED_PIN = 8
GREEN_LED_PIN = 9
# 定义红、绿、黄灯各自的持续时间
RED_LIGHT_DURATION = 10 # 红灯亮 10 秒
GREEN_LIGHT_DURATION = 8 # 绿灯亮 8 秒
YELLOW_LIGHT_DURATION = 3 # 黄灯阶段总共持续 3 秒
YELLOW_BLINK_INTERVAL = 0.5 # 黄灯闪烁间隔 -
引脚初始化:使用
machine.Pin类创建三个对象,分别对应红、黄、绿灯。machine.Pin.OUT参数将引脚配置为输出模式,允许程序控制高低电平。# 初始化 LED 引脚为输出模式
red_led = machine.Pin(RED_LED_PIN, machine.Pin.OUT)
yellow_led = machine.Pin(YELLOW_LED_PIN, machine.Pin.OUT)
green_led = machine.Pin(GREEN_LED_PIN, machine.Pin.OUT) -
辅助函数:
all_lights_off()函数用于同时关闭所有 LED。在状态切换前调用此函数,可以确保没有灯处于意外点亮的状态,提高代码的健壮性。def all_lights_off():
"""一个辅助函数,用于关闭所有灯。"""
red_led.off()
yellow_led.off()
green_led.off() -
主循环逻辑:程序在一个无限循环
while True中依次执行三个阶段:- 绿灯阶段:先调用
all_lights_off()清除状态,点亮绿灯,并延时GREEN_LIGHT_DURATION秒。 - 黄灯闪烁:计算闪烁次数(总时长除以单次周期),通过
for循环控制黄灯交替亮灭,模拟警示效果。 - 红灯阶段:点亮红灯并延时
RED_LIGHT_DURATION秒。由于黄灯已在上一阶段结束时熄灭,此处直接点亮红灯即可。
- 绿灯阶段:先调用
-
异常处理:使用
try...except...finally结构增强程序的稳定性。except KeyboardInterrupt:捕获用户中断信号(如 Ctrl+C),允许程序优雅退出。finally:无论程序正常结束还是被中断,都会执行all_lights_off()关闭所有灯,防止硬件处于不确定状态。