任务要求:
利用板上的WS2812B RGB三色灯模拟交通灯,程序会轮流切换三个灯的状态,并根据按键的输入(中断或查询机制)调整交通灯的切换。
环境配置:
1、基于STEP Pico的嵌入式系统学习平台:
基于树莓派Pico的嵌入式系统学习平台专为嵌入式系统学习而设计,其可以通过C/C++以及MicroPython编程来学习嵌入式系统的工作原理和应用。
2、Thonny:
Thonny的调试器是专为学习和教学编程而设计的,针对初学者学习Python语言优化了很多工具上的方式和方法。Thonny有很多适合初学者的优点,如:调试的时候显示变量的值。例如在循环运行的过程中,可以在代码中直接高亮显示当前变量的值,在编程的过程中更容易了解变量的变化和计算过程,有利于更加直观地理解循环及变量。调试时,直观显示函数的调用过程;Thonny的包管理器可以图形化的搜索第三方包,然后进行加载并管理;在Python的解释器中选择不同的解释器,Thonny就会自动切换不同的开发模式,以方便当前硬件的开发。
Thonny针对学习Python而设计的诸多优化点,能够让使用者更好地理解代码的运行、深入计算机交互和使用语言完成任务。
设计思路:
除了对交通灯基础功能——模拟交通灯运行,以及通过按键控制灯的切换时间——的实现之外,本次设计的重点放在了侧重于实用性的方面,即在实际生活中可能使交通灯变得更加实用的设计。
实际中的十字路口由于时间段的不同(如早晚高峰),各个方向的车流量会发生很大的变化。如采用固定的红绿灯时长,就很可能由于交通状况的变化而产生通行时间的浪费,导致路口整体的效率降低。因此考虑用路口的摄像头获取该方向的车辆通行情况,判断其交通状况,并用指数滑动平均值的方式给出实时评价。通过这种方式对红绿灯时长进行及时调整,使其更好地适应当前情况,提高路口的通行效率。
流程图:
程序实现:
1、基本功能
利用板上WS2812B RGB三色灯的不同状态模拟交通灯。WS2812B是一个集控制电路与发光电路于一体的智能外控LED光源,内置RGB三色灯珠,每个灯珠控制需要24位数据,8Bit绿色亮度+8Bit红色亮度+8Bit蓝色亮度。多个灯珠组合在一起可形成灯带,灯带上的灯珠供电并联,灯珠根据自己锁存的数据完成对RGB三色灯的控制。本次实验中用WS2812B实现红、黄、绿三种颜色的交通灯,绿灯临近结束时会通过闪烁提示行人,并在结束后切换至黄灯作为过渡;红灯转变为绿灯则不设置黄灯。在多方向交通灯协作运行的系统中,对于互斥的方向,每个方向的红灯时间覆盖另一方向的绿灯和黄灯时间,保证各方向安全运行。
根据按键的输入调整交通灯的切换。当行人在红灯状态下按下按钮时,如果此时剩余时间较长且车流量指标较低,则可以缩短红灯的剩余时间,以提高通行效率。
def apply(time_remain, ema_traffic_flow):
if time_remain>5 and ema_traffic_flow<0.5:
print('Time reduces, remains =', time_remain-3,'s.')
return 1
else:
return 0
def red():
for i in range(1, 13):
ws2812b.on(i, "#ff0000")
def yellow():
for i in range(1, 13):
ws2812b.on(i, "#ffff00")
def green():
for i in range(1, 13):
ws2812b.on(i, "#00ff00")
def green_blink(n):
for i in range(0, n):
for i in range(1, 13):
ws2812b.on(i, "#00ff00")
time.sleep(0.3)
for i in range(1, 13):
ws2812b.off(i)
time.sleep(0.1)
while True:
green()
time.sleep(3)
green_blink(5)
yellow()
time.sleep(2)
red()
j = 0
while j<15:
time.sleep(1)
j += 1
if k1.value()==True:
if apply(15-j, ema_traffic_flow):
j += 3
2、实际应用设计
def ema(ema_traffic_flow, n_pass, n_wait):
q = sigmoid(0.5*(n_wait - n_pass))
ema_traffic_flow = 0.4*q + 0.6*ema_traffic_flow
return ema_traffic_flow
在设计红绿灯的时长时,选择了使用双曲正切函数,即tanh()。双曲正切函数是奇函数,且在整个实数域是单调递增函数,这也就意味着它的函数值可以直接反应其自变量的变化趋势。因此可以被用于调整时间的增减,如将红灯和绿灯的基准时间都设定为40秒,然后跟据先前计算出的EMA车流量指标计算增(减)量,以达到实时调节的效果。由于现实情况中某一时间段内的车流量不会出现太大变化,每轮红绿灯周期更新一次数据,可以很大程度地适应当前的交通状况,以求提高通行效率。
双曲正切函数的图像夹在水平直线y=1及y=-1之间,当x的绝对值很大时,它的图形在第一象限内接近于直线y=1,而在第三象限内接近于直线y=-1。有界性使其变化幅度被限制在一定限度内,如变化幅度上限为10秒。虽然由于计算方式的适应性,即使不过多限制时间改变量也能在后续调整中平衡,但需要留出基本通行时间。双曲正切函数在自变量靠近0时斜率较大,因此将概率分布最集中的情况缩放至这一范围,如x∈(-2.5, 2.5),使其对自变量变化更敏感。
def duration_green(ema_traffic_flow):
t_green = 35 + 10*tanh(6*(0.5 - ema_traffic_flow))
return t_green
def duration_red(ema_traffic_flow):
t_red = 40 + 10*tanh(6*(ema_traffic_flow - 0.5))
return t_red
功能展示: