1 项目介绍
目标:制作一个交通灯控制器
具体要求:仿真马路上的交通灯的工作状态切换,利用板上的LED灯的红、黄、绿三种颜色切换显示道路状态的切换,行人按键时,具有优先功能,下一轮红灯亮时会发出蜂鸣警报,提醒行人。
实现方式:利用板上的LED灯模拟交通灯,程序会轮流切换三个灯的状态,并根据按键的输入(中断或查询机制)调整交通灯的切换。
2 设计思路
首先完成最基本的交通灯红、黄、绿颜色切换功能,通过ws2812b函数控制板卡上的一圈12个led灯的颜色变化与开关,然后通过time函数控制不同颜色信号灯持续的时间。
然后,通过button函数获取板卡上K1的控制,程序能够检测,当按下K1后进行反馈,在下一轮的红灯亮时进行蜂鸣提醒以及屏幕上显示“Please Go!”提醒。最后是功能拓展,通过利用oled函数,在屏幕上显示各种颜色信号灯的剩余持续时间,即完成一个倒计时功能,在各种颜色信号灯亮的同时,屏幕上会显示“Time: i S”,其中i是该信号灯的剩余时间。
3 软件流程图
图3-1 是软件工作流程图。从图中可以看出,当完成一轮信号灯工作之后才会检测是否按下K1键,检测到按下K1键之后,会进行相应的工作,即红灯亮、发出蜂鸣警报、屏幕显示提示信息。之后会检测在这次蜂鸣警报期间是否再次按下K1键,如果检测为是,则继续延长红灯时间,并且发出提示;如果检测为否,之后便会继续进行新的一轮信号灯工作循环,这就起到了延长红灯持续时间的效果。
图3-1 流程图
4 硬件介绍
图4-1、4-2是这次所用的板卡展示图。其中主要功能包括两个按键(K1、K2)、4种不同颜色的LED灯(LED_Y、LED_R、LED_G、LED_B)、12个RGB LED(可改变颜色)、一个蜂鸣器(BUZZER)、模拟输入(电位计输入、Microphone输入)、OLED显示、姿态传感器等等。在这次项目中主要用到板卡下侧的RUN按键、左侧的K1按键、上侧的蜂鸣器,还有板卡中间的显示屏以及周围一圈12个LED灯。
图4-1(左)、图4-2(右)
5 完成的功能及达到的性能 5.1 红、黄、绿三种颜色切换
运行程序之后,12个RGB LED灯会由“红”、“黄”、“绿”、“黄”、“红”的顺序循环变化,其中红灯持续时间设置为8秒,黄灯3秒,绿灯8秒。具体如图5-1、图5-2、图5-3。
图5-1 红灯
图5-2 黄灯
图5-3 绿灯
5.2 行人按键优先功能
当按下“K1”后,在下一轮交通灯变化时,就会有蜂鸣警报并且有提示“Please Go!”,同时,起到延长红灯持续时间,便于行人通行的作用。如图5-4。
图5-4 提示
5.3 信号灯剩余时间倒计时功能
在交通灯开始工作后,可以看到在屏幕上会出现“Time: i S”,其中i是剩余时间。具体见图5-1、图5-2、图5-3。
6 主要代码片段及说明 6.1 主要变量函数说明
def print_j(msg): #屏幕显示
oled.text(msg,0,30)
oled.show()
oled.fill(0)
通过调用oled函数定义print_j,可以通过print_j完成在屏幕显示文本;
def xunhuang(cishu): #剩余时间倒计时
for i in range(cishu):
print_j("Time: "+str(cishu-i)+" S")
time.sleep(1)
结合time函数与之前定义的print_j函数,利用循环语句,根据输入的次数(预设的倒计时开始时间),完成倒计时功能,并在屏幕上以“Time: i S”的形式显示,其中i是剩余时间;
def pitch(frequency,duration=0): #蜂鸣声警报
pwm.freq(frequency)
pwm.duty_u16(3000)
time.sleep_ms(duration)
蜂鸣声警报函数的定义,方便在后面的主函数中使用;
def red_light(): #设置红灯亮、黄灯亮、绿灯亮
for i in range(1,13):
ws2812b.on(i,"#ff0000")
def yellow_light():
for i in range(1,13):
ws2812b.on(i,"#ffff00")
def green_light():
for i in range(1,13):
ws2812b.on(i,"#00ff00")
通过调用ws2812b函数来控制板卡上RGB LED灯的开关以及颜色变化,实现红灯亮、黄灯亮、绿灯亮的效果。
6.2 主要循环函数说明
while True:
if k1.value()==True: #判断行人是否按下按钮
red_light() #延长红灯时间
print_j("Please Go!")
for i in range(0,10): #发出警报,提醒行人
for freq in range(352, 1760, 16):
pitch(freq, 3)
for freq in range(1760, 352, -16):
pitch(freq, 3)
pwm.deinit() #关闭警报
else:
red_light()
xunhuang(8) #红灯亮8秒,同时进行倒计时
yellow_light()
xunhuang(3) #黄灯亮3秒,同时进行倒计时
green_light()
xunhuang(8) #绿灯亮8秒,同时进行倒计时
yellow_light()
xunhuang(3) #黄灯亮3秒,同时进行倒计时
当程序开始运行后,便主要围绕这个循环实现交通灯的控制。在程序刚开始运行第一次循环时,由于无法检测K1键之前的状态,会直接进行一次红绿灯的规律变化。而在之后的每轮循环开始时会进行判断之前的循环中是否按下K1键,即模拟行人是否按键,如果检测到按下了K1键则会延长红灯时间并且进行蜂鸣警报,而且,如果在警报期间再次按下K1键,则会继续执行红灯延长,发出提醒的功能,直到检测为否,进行红绿灯规律变化。
7 遇到的主要难题及解决方法
在本次活动中,我遇到的主要问题是第一次接触这种嵌入式系统的学习,但在学习的过程中有相关课程的帮助我逐渐熟悉了相关的操作。通过课程学习,完成了软件环境的安装。在选定项目2制作交通灯控制器之后,我看了相关的课程讲解,能够跟上老师的进度,顺利完成了项目的基础功能,能够完成模拟马路上的交通灯切换,行人按键后具有优先功能。之后主要的问题是如何添加额外功能,我初步设想是增加一个倒计时功能,在屏幕上显示出信号灯剩余的时间。通过继续学习相关课程,了解到了oled函数,通过调用oled函数完成了在屏幕上显示倒计时。之后也学习了buzzer函数的相关内容,对蜂鸣警报的声音进行改变。
8 未来的计划
在本次活动中我学习到了如何利用Micro Python在Thonny上进行软件编程,对基于STEP Pico的嵌入式系统学习也有了基本认识,通过课程学习,最后完成了项目2,同时也添加了一些额外功能。
本次活动极大的激发了我对于嵌入式系统学习的兴趣,也希望继续学习嵌入式系统达的相关知识。在本次活动结束之后,我想继续去做=完成课程中的其他几个有趣的项目,之后自己去网上了解学习更多的有关应用。
最后,非常感谢硬禾学堂能够提供这样一次学习认识嵌入式系统的机会,在完成项目的过程中我收获颇丰,希望以后能够继续参加硬禾学堂的活动。