基于STEP Pico制作交通灯控制器
一、项目描述
1. 项目介绍
基于STEP Pico嵌入式系统开发板,使用micropython编程,制作交通灯控制器
(1)具体要求:仿真马路上的交通灯的工作状态切换,利用板上的红、黄、绿三种颜色的LED显示道路状态的切换,行人按键时,具有优先功能;
(2)实现方式:利用板上的3个不同颜色的LED模拟交通灯,程序会轮流切换三个灯的状态,并根据按键的输入(中断或查询机制)调整交通灯的切换。
2. 设计思路
(1)编写点亮单色LED及WS2812B RGB三色灯程序,实现交通灯红黄绿三种颜色的切换;
(2)编写时序程序,实现交通灯根据指定时间循环切换的基本功能;
(3)调用按键,实现根据按键的输入调整交通灯的切换;
(4)调用OLED显示屏,在屏幕上实时显示交通灯的剩余持续时间。
3. 软件框图
二、硬件介绍
1. 嵌入式系统学习平台
(1)硬禾版本树莓派Pico核心模块 - STEP Pico x1;
(2)树莓派Pico扩展板 x1。
Step pico是一款低成本,高性能的微控制器开发板,具有灵活数字接口(完全兼容Raspberry Pi Pico)。
2. 板卡硬件
(1)按键;
(2)单色LED;
(3)WS2812B RGB三色灯;
(4)128*64 OLED显示屏。
三、项目功能
仿真马路上的交通灯的工作状态切换,利用板上的红、黄、绿三种颜色的LED和WS2812BRGB三色灯显示道路状态的切换、模拟交通灯,并通过OLED显示屏显示交通灯的剩余持续时间。程序会轮流切换三个灯的状态,行人按键时,具有优先功能,根据按键的输入,调整交通灯的切换。
(1)一般状态下,绿灯持续5秒,黄灯持续3秒,红灯持续5秒;
(2)按下按键后,下一次到来的红灯持续时间将被延长至10秒。
图片说明
(1)绿灯状态,绿色LED亮,RGB三色灯为绿色,OLED屏显示时间,持续5秒;
(2)黄灯状态,黄色LED亮,RGB三色灯为黄色,OLED屏显示时间,持续3秒;
(3)红灯状态,红色LED亮,RGB三色灯为红色,OLED屏显示时间,持续5秒;
(4)行人按键后的红灯状态,红色LED亮,RGB三色灯为红色,OLED屏显示时间,持续10秒;
四、代码说明
1. 初始化
from button import k1
from board import pin_cfg
from led import g, y, r
import time
from oled import oled
import ws2812b
调用板卡、时间、以及本项目所需要的LED灯、OLED显示屏、及WS2812B RGB三色灯。
green = "#00ff00"
red = "#ff0000"
yellow = "#fff00"
定义常量green、red及yellow,用于通过WS2812B RGB三色灯实现绿、黄、红三种颜色。
g.off()
y.off()
r.off()
ws2812b.off_all()
将所有LED及WS2812B RGB三色灯置于“off”状态,初始化。
2. 定义主要函数
(1)OLED显示屏显示数字函数showtext(),n为要显示的数字
def showtext(n):
oled.fill(0)
oled.text("{0}".format(n),0,0)
oled.show()
在OLED显示屏显示数字需要三个步骤:
将当前显示屏上的数字清除;
在显示屏的(0,0)位置输出n所对应数字的文本;
将文本展示在显示屏上。
该函数实现功能:将输入数字显示在OLED显示屏上。
(2)绿灯亮函数g_light(i),i为绿灯持续时间(秒)
def g_light(i):
g.on()
ws2812b.on(12,green)
点亮绿色LED;
将12号WS2812B RGB三色灯置于“绿色”状态。
while i>0:
showtext(i)
time.sleep(1)
i -= 1
循环语句。在OLED显示屏显示数字i,持续1秒,i减1,直至i=0。
g.off()
关闭绿色LED。
该函数实现功能:点亮绿色LED及绿色WS2812B RGB三色灯,持续i秒,每秒调用一次OLED显示屏显示数字函数showtext(),然后关闭。
黄灯亮函数与红灯亮函数与该函数类似。
def y_light(j):
y.on()
ws2812b.on(12,yellow)
while j>0:
showtext(j)
time.sleep(1)
j -= 1
y.off()
def r_light(k):
r.on()
ws2812b.on(12,red)
while k>0:
showtext(k)
time.sleep(1)
k -= 1
r.off()
3. 主循环
while True:
g_light(5)
y_light(3)
if k1.value() == True:
r_light(10)
else:
r_light(5)
实现功能:
绿灯亮5秒,并显示时间;
黄灯亮3秒,并显示时间;
若收到按键请求,则红灯亮10秒,并显示时间;
若没收到按键请求,则红灯亮5秒,并显示时间;
五、主要问题
1. 如何点亮和熄灭LED?
调用led文件,通过g.on()、g.off()来实现绿色LED的亮灭。
2. 如何点亮和熄灭WS2812B RGB三色灯?
调用ws2812b文件,通过ws2812b.on(12, "#00ff00")来指定12号灯呈现绿色;通过ws2812b.off_all()熄灭所有三色灯。
3. 如何获取按键信息?
通过from button import k1获取按键k1信息。若k1被按下,k1被置为True;若不按k1 ,则k1 为False。
4. 如何在OLED屏显示文本?
通过oled.fill(0)清屏;
通过oled.text("text",0,0)输入要显示的文本;
通过oled.show()显示文本。
5. 如何实现时间延迟?
time.sleep(1)可实现1s的延迟。
6. 如何使交通信号灯具备屏幕显示时间功能?
使用循环套循环的方法,在主循环中添加每秒显示时间并步进的循环,来实现此功能。
7. 如何提高程序可读性?
可将程序的4个主要功能编写成函数,提高程序可读性的同时,易于修改程序参数。
8. 程序是否有冗余部分?
注意到,一般红灯状态与按键后红灯状态可用一个函数来实现,可删除一个冗余的函数。
六、完整程序代码
1. 主程序traffic-lights-2.py
from button import k1
from board import pin_cfg
from led import g, y, r
import time
from oled import oled
import ws2812b
green = "#00ff00"
red = "#ff0000"
yellow = "#fff00"
g.off()
y.off()
r.off()
ws2812b.off_all()
def showtext(n):
oled.fill(0)
oled.text("{0}".format(n),0,0)
oled.show()
def g_light(i):
g.on()
ws2812b.on(12,green)
while i>0:
showtext(i)
time.sleep(1)
i -= 1
g.off()
def y_light(j):
y.on()
ws2812b.on(12,yellow)
while j>0:
showtext(j)
time.sleep(1)
j -= 1
y.off()
def r_light(k):
r.on()
ws2812b.on(12,red)
while k>0:
showtext(k)
time.sleep(1)
k -= 1
r.off()
while True:
g_light(5)
y_light(3)
if k1.value() == True:
r_light(10)
else:
r_light(5)
2. board.py
3. button.py
4. led.py
5. oled.py
6. ws2812b.py
7. ssd1306.py