项目二——制作交通灯控制器的总结报告
1.项目介绍:仿真马路上的交通灯的工作状态切换,利用ws2812b的12个串联的RGB灯进行红,黄,绿三种颜色的切换。此交通灯是以行人视角所设计的,程序会轮流切换三个灯的工作状态,在无行人想要通过时,按照绿灯(10s)→黄灯(2s)→红灯(10s)→黄灯(2s)的周期进行循环,并且oled屏幕上会显示太空小人,当绿→黄时,小太空人前进,当红→黄时,太空小人停止前进。如果有行人想要通过马路时,可以按下k1或者k2按钮获得优先通过权。行人按下按钮后,在下一个循环的绿灯亮起时,会鸣笛循环10次,鸣笛时间即为所延长提供给行人的通过时间。
2.设计思路:按照社会上普遍的交通信号灯的时长,设计为绿灯(10s)→黄灯(2s)→红灯(10s)→黄灯(2s)为一周期的循环。并且引入按键,使有行人通过时,获得优先使用权,延长行人通过时间,确保其安全,并且通过鸣笛提示的方式,令患有缺陷或视觉障碍的人也获得可以通过的信号。
下图为RP2040 PICO的PINOUT示意图:
3.编写主函数之前的准备工作:
1)首先,引入主函数中所运用到的oled模块,以及它运行时所依赖的module
import ws2812b
import utime, time
import _thread
from machine import SPI, Pin
from ssd1306 import SSD1306_SPI
import framebuf
2)从board中引入PIN 引脚
from board import pin_cfg
import gc
3)从button中引入K1,K2按键,来实现led灯的控制
from button import k1
from button import k2
4)create PWM object from a pin
pwm = PWM(Pin(pin_cfg.buzzer))
5)引入蜂鸣函数
def pitch(frequency, duration=0):
pwm.freq(frequency)
pwm.duty_u16(3000)
time.sleep_ms(duration)
6)进行SPI的初始化
spi = SPI(1, 100000, mosi=Pin(pin_cfg.spi1_mosi), sck=Pin(pin_cfg.spi1_sck))
oled = SSD1306_SPI(128, 64, spi, Pin(pin_cfg.spi1_dc),Pin(pin_cfg.spi1_rstn), Pin(pin_cfg.spi1_cs))
此处意为开一个多线程函数,-thread意味多线程同时进行,本次项目的the-seconf-loop为oled屏幕上随着交通等的变化而进行前进或停止的小太空人。
_thread.start_new_thread(the_second_loop, ())
7)对RGB灯三种颜色进行赋值定义,主函数中用“green red yellow”来表示颜色的切换。
green = "#00ff00"
red = "#ff0000"
yellow = "#fff00"
4.本次项目所运用到的硬件介绍:
板卡的硬件由:
2个按键输入
4个单色LED
12个WS2812B RGB三色灯
1个姿态传感器
1个128*64 OLED显示屏
1个蜂鸣器
1个可调电位计(用于电压表)
1路音频信号输入(用于示波器)
8位R-2R电阻网络构成的DAC(用于DDS信号发生器)
组成
5.实现的功能及图片展示:此交通灯是以行人视角所设计的,程序会轮流切换三个灯的工作状态,在无行人想要通过时,按照绿灯(10s)→黄灯(2s)→红灯(10s)→黄灯(2s)的周期进行循环,并且oled屏幕上会显示太空小人,当绿→黄时,小太空人前进,当红→黄时,太空小人停止前进。如果有行人想要通过马路时,可以按下k1或者k2按钮获得优先通过权。行人按下按钮后,在下一个循环的绿灯亮起时,会鸣笛循环10次,鸣笛时间即为所延长提供给行人的通过时间。
6.流程图
7.主要代码片段及说明:
1)该函数表示的是多线程函数中的太空人前进代码,定义state=1时,前进。state=0时静止不动
def the_second_loop():
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()
2)if函数,“True”表示按键按下,当K1或者K2有任意一个按键按下时即可启动该if下的语句。
ws2812b上的绿灯即全部亮为绿色。
if k1.value()==True or k2.value()==True:
ws2812b.on_all(green)
state = 1
print("+5 start")
3)按键 按下后会在电脑端打印“+5 start”语句,以此标记开始鸣笛,当鸣笛结束时,在电脑端打印“+5 end”语句表示鸣笛结束。
print("+5 end")
pwm.deinit()#意为在pin上关闭pwm
4)下面程序就是交通灯信号的循环,红 黄 绿依次亮起,其中还运用到了延迟函数,以此来控制延长灯亮起来的时间。
ws2812b.on_all(green)
state = 1
time.sleep(10)
ws2812b.on_all(yellow)
time.sleep(3)
state = 0
ws2812b.on_all(red)
time.sleep(10)
ws2812b.on_all(yellow)
time.sleep(3)
7.难题及解决方法:首先,我本来想运用以下oled输出文字函数,令其搭配着太空人的运动分别输出“You can go”或者”Pleas
e wait for a second“的字母,来提示行人,但是在运行时,在程序编写全部正确的情况下,oled屏幕上显示的却是”*******************“一串错误的提示,因是在端口输出时出现冲突与矛盾,使信号处理错乱。因此我选择去除掉文字提示编码,保留太空人图案进行行人的提示。
oled.fill(0)
oled.show()
#sleep(1)
oled.text("HELLO www.eetree.cn",i,j)
oled.show()
sleep_ms(50)
8.未来的计划或建议:我希望再改进一下在交通灯即将交换颜色时,可以有更加直观,方便观察到的提示,比如在12个RGB上也增添呼吸灯的设定,或可以实现从1箭头12号序列灯的,红 黄 绿以此循环点亮与熄灭,都是很好的提示行人通过的方式,但是因本人能力有限,未能实现在此相关程序的编写,希望在下次,对此项目进行更加细致的优化。希望此类可以让行人获得延长通过时间的交通灯可以在,行人颇多的上下班路口或学生放学的路口,进行投入使用,可进一步测验,丰富结论,进行交通灯的优化。
9.实物展示
ws2812b显示绿灯,oled屏幕小人通行
ws2812b显示黄灯,oled屏幕小人通行 警示行人即将红灯
ws2812b显示红灯,oled屏幕小人停止