项目2 - 制作一个交通灯控制器
项目描述
项目介绍:
仿真马路上的交通灯的工作状态切换,利用板上的红、黄、绿三种颜色的LED显示道路状态的切换,行人按键时,具有优先功能。
设计思路:
搭建Thonny集成开发环境,使用microPython语言进行程序开发。由浅入深,首先,实现程序轮流切换LED灯的三种颜色实现模拟道路状态的切换。然后,在能够模拟交通灯切换颜色的基础上,引入K1按键功能,模拟行人发起过马路请求,将下一个红灯的时间延长,以便行人穿过马路。至此,完成项目要求的基本功能。
在项目要求的基本功能之外,我结合日常生活中观察到的交通灯,添加了一些额外功能,使得项目模拟的交通灯更贴近现实:我引入了Buzzer蜂鸣器的功能,在行人按键后的下一个红灯进行警报,模拟行人过马路对过往车辆的提醒功能。除此之外,我还利用了嵌入式系统学习平台上的SSD1306显示屏,模拟红绿灯里的行人小人。
软件流程图:
硬件介绍
本次2023寒假在家练我使用的是硬禾学堂研发的基于树莓派Pico的嵌入式系统学习平台,该平台专为嵌入式系统学习而设计,其可以通过C/C++以及MicroPython编程来学习嵌入式系统的工作原理和应用,具体可以参考https://www.eetree.cn/project/detail/584。
平台由一个树莓派Pico扩展板和一个硬禾版本树莓派Pico核心模块——STEP Pico组成,STEP Pico是一款低成本,高性能的微控制器开发板,具有灵活数字接口(完全兼容Raspberry Pi Pico)。硬件上,采用Raspberry Pi官方自主研发的RP2040微控制器芯片,搭载了ARM Cortex M0+双核处理器,高达133MHz的运行频率,内置了264KB SRAM和2MB闪存,还板载有多达26个多功能的GPIO引脚。软件上,可选择树莓派提供的C/C++SDK,或者使用MicroPython进行开发且配套有完善的开发资料教程,可方便快速入门开发并嵌入到产品中。
除了STEP Pico核心板外,我还用到了以下硬件:
1个按键输入K1;
12个WS2812B RGB三色灯;
1个128*64 OLED显示屏
1个蜂鸣器
实现的功能
1. 实现程序轮流切换LED灯的三种颜色实现模拟道路状态的切换
程序运行后,LED灯的颜色会由5秒红灯变为5秒绿灯,再由5秒绿灯变为2秒黄灯,之后变为5秒红灯,如此循环。为了便于演示,我将红绿灯的时间设置的较短,实际上可以根据实际路况设置。
实际效果如图所示:
运行后LED灯显示红灯,模拟红灯状态。
根据生活经验,红灯后为绿灯。故红灯5秒后LED灯显示绿灯,模拟绿灯状态
绿灯5秒后LED灯显示黄灯,模拟黄灯状态,保持2秒后变为红灯继续循环。
2. 模拟行人发起过马路请求,将下一个红灯的时间延长
轻按如图所示的K1按钮,即为模拟行人想要过马路的场景,在当前车道的绿灯黄灯结束后(不影响正在因绿灯正在通行的车辆),将下一次红灯的长度延长10秒以便行人穿过马路,受限于图片形式,该功能具体效果我将在视频中展示。
3. 引入了Buzzer蜂鸣器的功能,在行人按键后的下一个红灯进行警报
在功能2的情境下,行人按下了过马路按钮(K1按钮),车道下一个红灯将延长10秒以便行人通过。与此同时,蜂鸣器将工作,发出报警声提醒司机注意行人通过。
4. 模拟红绿灯里的行人小人
在生活中,人行道的红绿灯通常是一个小人:在红灯时保持静止,在绿灯(黄灯)时向前走动,我利用学习平台上的SSD1306显示屏,进行一个正在通过屏幕的小人的显示,并且随着红灯停下。鉴于此部分为动态过程,我将在视频中进行演示,如图为小人红灯停下和绿灯(黄灯)向前走的示意。
主要代码片段
1. 实现交通灯颜色变化、按键延长红灯以及蜂鸣的循环
#进入循环,实现交通灯控制
while True:
#如果行人按下K1按钮,则为True,进入if语句,实现红灯延长
if k1.value() == True:
#首先延长红灯时间
ws2812b.on_all(red)
state = 0
#发出蜂鸣声警告车辆注意行人
for i in range(10):
for freq in range(880, 1760, 16):
PWM(Pin(pin_cfg.buzzer)).freq(freq)
PWM(Pin(pin_cfg.buzzer)).duty_u16(3000)
time.sleep_ms(6)
for freq in range(1760, 880, -16):
PWM(Pin(pin_cfg.buzzer)).freq(freq)
PWM(Pin(pin_cfg.buzzer)).duty_u16(3000)
time.sleep_ms(6)
#警报结束
PWM(Pin(pin_cfg.buzzer)).deinit()
#红灯5秒
ws2812b.on_all(red)
state = 0
time.sleep(5)
#鉴于生活中红灯后为绿灯,此处我注释掉了红灯后的黄灯2秒
#ws2812b.on_all(yellow)
#time.sleep(2)
#红灯后绿灯5秒
ws2812b.on_all(green)
state = 1
time.sleep(5)
#绿灯后黄灯2秒
ws2812b.on_all(yellow)
time.sleep(2)
其中,用判断在检测到K1按键被按下后,在下一次循环开始时,将灯的颜色设置为红色,将state置为0(接下来会讲到这时屏幕上的小人停下)。
#如果行人按下K1按钮,则为True,进入if语句,实现红灯延长
if k1.value() == True:
#首先延长红灯时间
ws2812b.on_all(red)
state = 0
随后进入延长的10秒红灯,此时蜂鸣器进行警报。
#发出蜂鸣声警告车辆注意行人
for i in range(10):
for freq in range(880, 1760, 16):
PWM(Pin(pin_cfg.buzzer)).freq(freq)
PWM(Pin(pin_cfg.buzzer)).duty_u16(3000)
time.sleep_ms(6)
for freq in range(1760, 880, -16):
PWM(Pin(pin_cfg.buzzer)).freq(freq)
PWM(Pin(pin_cfg.buzzer)).duty_u16(3000)
time.sleep_ms(6)
#警报结束
PWM(Pin(pin_cfg.buzzer)).deinit()
随后走出(K1被按下)判断,实现红灯绿灯和黄灯的切换,不难注意到,在红灯时,我将state变量置为0,在绿灯和黄灯时,state变量为1,这涉及到接下来显示屏小人的状态(0时静止不动,1时向右移动)。
#红灯5秒
ws2812b.on_all(red)
state = 0
time.sleep(5)
#鉴于生活中红灯后为绿灯,此处我注释掉了红灯后的黄灯2秒
#ws2812b.on_all(yellow)
#time.sleep(2)
#红灯后绿灯5秒
ws2812b.on_all(green)
state = 1
time.sleep(5)
#绿灯后黄灯2秒
ws2812b.on_all(yellow)
time.sleep(2)
最后,关于K1的判断和红绿黄灯的切换一起作为一个真循环,实现交通灯的控制功能。
2. 实现显示屏小人的移动和停止的循环
#用state控制小人走动
#state=0则小人停下,state=1则小人移动
global state
x = -64
fb = [framebuf.FrameBuffer(frames[fr], 64, 64, framebuf.MONO_HLSB)
for fr in range(0, 48)]
while True:
for fr in range(0, 48):
if state == 0: continue
oled.blit(fb[fr], x, 0)
gc.collect()
utime.sleep_ms(40)
if x < 128:
x = x + 1
else:
x = -64
print(x)
oled.show()
其中定义了一个全局变量state,在前面提到了state为0和1的两种状态。在state为0时,用continue语句跳出本次循环,实现小人的静止。
for fr in range(0, 48):
if state == 0: continue
oled.blit(fb[fr], x, 0)
gc.collect()
utime.sleep_ms(40)
if x < 128:
x = x + 1
else:
x = -64
print(x)
oled.show()
遇到的主要难题及解决方法
我虽然有一些编程基础,但是并没有进行过microPython甚至是python语言的学习,这对于我一开始的编程开展产生了一些困扰。
在老师的指导下,我学会了查阅开源的Gitee代码,并通过查阅python相关函授的意义,帮助我对代码进行理解,逐渐发现编程语言之间的相似性,对知识进行消化吸收,并尝试自己进行了代码的编写。
未来的计划和建议
通过本次2023寒假一起练的机会,我利用基于树莓派Pico的嵌入式系统学习平台实现了基础的交通灯转换,以及行人按钮功能。之后,继续融入了蜂鸣器警报和显示屏显示的功能,让自己的交通灯功能更加丰富。
经过了这次的深入研究,我领会到了学习平台的魅力,收获了乐趣,我也更明白它的强大功能不只于此。在未来,我会结合手上的学习平台,持续关注相关信息,学习有关知识,实现更多有趣的功能!
编程是我非常感兴趣的领域,虽然没有预先学习过microPython,在老师们耐心的指导下,我结合老师分享的开源gitee代码进行学习与尝试,结合学习其他编程语言的经验,努力完成了任务,我也一直想进行python等编程语言的学习,这一次的实践对我来说是一次很棒的鼓励。
最后,感谢硬禾能提供更多的机会,让我们在实践操作的乐趣中汲取知识,我也希望这样的机会多多益善。