硬件介绍:
该平台采用Raspberry Pi官方自助研发的RP2040微控制器芯片,搭载ARM Cortex M0+双核处理器,内置有264KB SRAM和2MB内存,还板载有多达26个多功能的GPIO引脚。软件上可采用MicroPython进行开发。
项目要求:
利用板上的3个不同颜色的LED模拟交通灯,程序会轮流切换三个灯的状态,并根据按键的输入调整交通灯的切换。
设计思路:
我想要模拟我国实际红绿灯逻辑,即红灯亮完绿灯亮,绿灯亮完黄灯亮,黄灯亮完红灯亮。另外,对于行人优先按键的加入,我决定设置为:
若在红灯期间按下按键,将会在基础红灯时间后额外加一个延长时间;若在绿灯期间按下按键,将会立即结束绿灯流程并跳转到黄灯流程,进而转换为红灯,之所以没有设置为立即转为红灯,是为了给司机一个缓冲的反应时间,防止发生交通事故。
当上电系统启动后,首先执行红灯亮5秒的程序,并利用线程检测是否有按键按下:若按下按键,在红灯亮5秒后执行红灯延长4秒程序;若没有按下按键,接着执行主循环。红灯以及延长的红灯结束后,执行绿灯亮5秒程序。下图为本系统程序流程图:
代码介绍:
首先在主循环的程序开头加入确保所有灯处于关闭状态的语句:
red.off()
yellow.off()
green.off()
然后执行红灯亮5秒程序stop():
def stop(): #执行红灯亮5秒后灭
red.on()
for i in range(5):
oled.fill(0)
oled.text("Please wait", 0, 0)
oled.text(str(5-i), 55, 20)
oled.show()
time.sleep(1)
red.off()
并且利用线程检测红灯亮的过程中按键是否按下,需要在主循环程序之前创建一个全局变量,并给他一个默认值False,意思是当程序开始时按键还没有按下:
global button_pressed #设置一个全局变量
button_pressed = False #并赋一个初始值False
下一步是定义线程,直接在下面添加以下几行,第一行定义了线程名称,下一行让MicroPython知道我即将更改全局变量的值,接着设置一个新的循环,这个循环也是线程的一部分:
def button_reader_thread():
global button_pressed
while True:
if button.value() == 0:
button_pressed = True
utime.sleep(0.01)
在上面这个循环中,第一行是一个条件语句,用于检查按键的值是否为1, Pico使用一个内部的上拉电阻,当按键没有被按下时,读取的值是1,这意味着在此条件下代码永远不会运行, 只有当按键被按下时,读取的值才为0,线程的最后一行才会运行,这一行将button_pressed变量设置为True,让程序的其余部分知道按键已经被按下。最后,我们添加了一个非常短(0.01秒)的延迟,以防止while循环运行过快。
在线程下面创建一个新行,如下所示:
_thread.start_new_thread(button_reader_thread, ())
这告诉_thread库启动前面定义的线程。在这一点上,线程将开始运行并快速进入它的循环, 每秒检查按键数千次,看看它是否被按下。与此同时,主线程将继续执行程序的主要部分。
红灯或红灯延长程序执行完毕后,进入亮绿灯程序:
green.on() #绿灯亮
for k in range(5):
if button_pressed == True: #在亮绿灯程序中检测案件是否被按下,若按下立即跳出亮绿灯的读秒循环程序
global button_pressed
button_pressed = False
break
oled.fill(0)
oled.text("Permit passage", 0, 0)
oled.text(str(5-k), 90, 20)
oled.show()
time.sleep(1)
green.off() #绿灯灭
从上面这个程序可以看出,我在绿灯每次读秒时检测按键是否按下,若按下,将执行break语句直接跳出for循环,即接着执行green.off()以及接下来的亮黄灯程序。若没有检测到按键按下,那程序将在执行亮绿灯5秒完毕后才会执行亮黄灯程序。
以下是亮黄灯程序:
def wait(): #执行黄灯亮3秒后熄灭
yellow.on()
for j in range(2):
oled.fill(0)
oled.text("Attention please", 0, 0)
oled.text(str(2-j), 0, 20)
oled.show()
time.sleep(1)
yellow.off()
功能展示:
上电后,红灯亮,正常读秒:
然后绿灯亮,正常读秒:
随后黄灯亮,正常读秒:
若在红灯期间按下按键,将进入延长时间:
若在绿灯期间按下按键,将会立即转入黄灯流程。具体展示请看视频介绍。
存在不足:
1、可以为该系统加入行车以及停止的动画,丰富显示效果;
2、还可以引入汉字字符库,使得屏幕显示汉字,便捷本地化应用。