基于STEP Pico的交通灯控制器
此次使用pico板实现了一个简易的交通灯控制小项目,借助板上其中的3颗LED灯,全真模拟现实交通灯的工作流程,红色LED亮表示车辆禁止通行,行人可通过;绿色LED亮表示车辆可通行,行人禁止通过;黄色LED与其中一颗闪烁,表交通状态即将改变。
标签
嵌入式系统
PICO
2023寒假在家练
yinwuqing
更新2023-03-29
470

一、项目介绍

        交通灯在日常生活中随处可见,尤其是在一线城市,一个交通灯的损坏,或会引发一场交通事故,或会造成交通堵成长龙,上班族迟到的后果。之前有采用51单片机制作过交通灯控制面板,使用C语言开发。此次在硬禾的Step Pico板子上,有4颗LED灯,分别为R(红色),G(绿色),B(蓝色),Y(黄色),由于交通灯为三色,故使用其中的R(红色),G(绿色),Y(黄色)灯来仿真实际生活中交通灯的工作状态。注:由于板上蜂鸣器声音过小,所以笔者外接自购的蜂鸣器。

        项目中指示灯无人控制下,三盏灯的运作状态如下:

①、开始红色LED点亮,OLED屏显示行人图样。此时车辆禁止通行,行人可顺利通过。

②、红色LED与黄色LED同时闪烁3秒,提醒行人即将禁止通过,司机做好开车准备。

③、绿色LED点亮,OLED熄屏,此时车辆可顺利通行,行人禁止通过马路。

④、绿色LED与黄色LED同时闪烁3秒,提醒司机即将禁止通行,行人做好通过马路的准备。

二、设计思路

       由于只是借助pico板上集成的3盏LED灯,模拟单条马路上,车辆与行人有序安全通过,行人观察LED灯状态可能需要斜眼查看,因此引入按钮+OLED屏+蜂鸣器来提醒行人高效出行。

FrPmo_8mnVCYHoFRLjz7ZG4ybEfr

          为了确保行人更安全通过,这里引入按钮控制交通灯状态,当有行人按了按钮后,产生一个标识状态,当运行的线程到下一周期的行人可通过状态,响起蜂鸣器提示行人,并等蜂鸣器停止鸣叫之后,继续进行默认的红灯点亮时长,再加上黄灯的闪烁环节,这样更有保障。

设计框图如下:

FmSUv16nS0Do97U-F8e8IgI3XaBU

三、硬件资源

       Step Pico板上资源丰富,交通灯项目运用到硬件资源有:RP2040微控制器,按键K1,OLED屏,蜂鸣器,R、G、Y三颗指示灯,这里着重介绍一下RP2040微控制器。

◆ 双核Arm Cortex M0 +处理器,时钟频率高达133 MHz

◆ 264KB的SRAM和2MB的板载闪存

◆ 通过USB使用大容量存储进行拖放编程

◆ 26个多功能GPIO引脚

◆ 2个SPI,2个I2C,2个UART,3个12位ADC,16个可控PWM通道

◆ 片上准确的时钟和计时器

RP2040通过焊接在板上的排针与底板相连接,使用的硬件连线示意图如下:

FsWZrc4PkiZMEdZlpSLy3f3Zc21m

电路原理图如下:

FqJwujzV2M3z7EIk_SBjIuE0BOcJ

四、实现功能

         引入线程,行人通过按钮来开启全局标志变量button_pressed,当主线程执行到检测标志变量button_pressed时,为真时则触发蜂鸣器,并将标志变量button_pressed关闭;为假时则不用跳转到另一线程。按键稍加延时,用以消抖。为了确保每次OLED屏周期性从初始位显屏,将在子线程中设置X坐标为-64;为确保每次熄屏后不残留图样信息,稍加延时消隐处理。

软件流程图如下:

FjMnOQE7QDdxhoVRyFmSA9X5QNPs

五、图片展示

Fg_xwdDP1t6XMY-Yg4eErws4reslFojDN-0vHWIxF2pXBeCuzPQhJM2kFiDD0q3N1PgnOsTKXw9X6A-mmtuS

FnaEAJK83iG_-l03Lhyxx0EVXB1iFnYH4OuZMiOKlQuMEdiqVH7IyY1G

六、主要代码片段展示

import machine         #导入machine库
import utime             #导入utime库
import _thread          #导入thread库

from machine import SPI, Pin
from ssd1306 import SSD1306_SPI
import framebuf
from astronaut import frames       #从astronaut图形库中引入frames变量,需要在同一目录下加载astronaut.py文件
from board import pin_cfg
import gc

global button_pressed                   #定义按键是否按下的全局变量
button_pressed = False

led_red = machine.Pin(26,machine.Pin.OUT)                                #配置红灯的管脚属性
led_yellow = machine.Pin(20,machine.Pin.OUT)                           #配置黄灯的管脚属性
led_green = machine.Pin(22,machine.Pin.OUT)                            #配置绿灯的管脚属性
button = machine.Pin(12,machine.Pin.IN,machine.Pin.PULL_UP) #配置按键的管脚属性
buzzer =  machine.Pin(19,machine.Pin.OUT)                                #配置蜂鸣器的管脚属性

spi = SPI(1, 100000, mosi=Pin(pin_cfg.spi1_mosi), sck=Pin(pin_cfg.spi1_sck))    #配置SPI的管脚及波特率等属性
oled = SSD1306_SPI(128, 64, spi, Pin(pin_cfg.spi1_dc),Pin(pin_cfg.spi1_rstn), Pin(pin_cfg.spi1_cs))  #定义OLED采用SPI驱动的管脚配置
oled.fill(0)       #初始化清屏      
state = 1        #点亮OLED屏

def oled_display_loop():
    global state                         #点亮屏的全局标志位
    global button_pressed        #按键被触发的全局标志位
    x = -64                                #每次刷图的X坐标的起始点
    fb = [framebuf.FrameBuffer(frames[fr], 64, 64, framebuf.MONO_HLSB)     #调用astronaut图形库中的每一帧数组文件
          for fr in range(0, 48)]
    while True:
        if button.value() == 0:             #读取按键IO口是否为低电平,为低则触发了按键,标志位置true
            button_pressed = True
        utime.sleep(0.02)                    #按键消抖延时处理
        for fr in range(0, 48):
            if state == 0:                      #确保每次熄屏再次亮屏时,图样从固定起始位刷出,故对X坐标赋固定值
                x = -64
                continue
            oled.blit(fb[fr], x, 0)            #OLED读取fb数组文件
            gc.collect()
            utime.sleep_ms(1)
            if x < 128:                           #每隔1ms则X左移一个坐标
                x = x + 1
            else:
                x = -64
            print(x)
            oled.show()                        #OLED显示   
            
_thread.start_new_thread(oled_display_loop, ())   #启动OLED显示线程

while True:
    if button_pressed == True:
        state = 1
        led_red.value(1)         #有按键被按下触发过,说明有行人需要通过马路
        led_green.value(0)     #只亮红灯,禁止车辆通行
        led_yellow.value(0)   
        for i in range(20):      #蜂鸣器鸣叫20次,提醒行人可放心通过马路
            buzzer.value(1)
            utime.sleep(0.2)
            buzzer.value(0)
            utime.sleep(0.2)
        global button_pressed
        button_pressed = False   #释放按键被触发的状态标志位
    state = 1                              #点亮OLED屏,显示Astronaut图样
    led_red.value(1)                   #红灯常亮5秒,行人可通过马路,车辆禁止同行
    led_green.value(0)
    led_yellow.value(0)
    utime.sleep(5)
    led_red.value(1)                  #红灯与黄灯同时闪烁3s,提醒行人将要禁止通过状态
    led_yellow.value(1)             #此时提醒开车司机即将通行,做好驾车准备
    utime.sleep(0.5)
    led_red.value(0)
    led_yellow.value(0)
    utime.sleep(0.5)
    led_red.value(1)
    led_yellow.value(1)
    utime.sleep(0.5)
    led_red.value(0)
    led_yellow.value(0)
    utime.sleep(0.5)
    led_red.value(1)
    led_yellow.value(1)
    utime.sleep(0.5)
    led_red.value(0)
    led_yellow.value(0)
    utime.sleep(0.5)
    led_red.value(1)
    led_yellow.value(1)
    state = 0                        #熄灭OLED屏
    oled.fill(0)                      #清屏处理
    utime.sleep(0.5)
    oled.fill(0)                      #确保无残留图样
    utime.sleep(0.5)
    led_red.value(0)
    led_green.value(1)        #绿灯常亮5秒,车辆可同行,行人禁止通过马路
    led_yellow.value(0)
    utime.sleep(5)
    led_yellow.value(1)       #绿灯与黄灯同时闪烁3s,提醒司机即将禁止通行
    utime.sleep(0.5)             
    led_green.value(0)
    led_yellow.value(0)
    utime.sleep(0.5)
    led_green.value(1)
    led_yellow.value(1)
    utime.sleep(0.5)
    led_green.value(0)
    led_yellow.value(0)
    utime.sleep(0.5)
    led_green.value(1)
    led_yellow.value(1)
    utime.sleep(0.5)
    led_green.value(0)
    led_yellow.value(0)
    utime.sleep(0.5)
    led_green.value(1)
    led_yellow.value(1)
    

值得注意的是,正如视频https://v.youku.com/v_show/id_XNTk0NjYzMzE0MA==.html中介绍的内容一样,加载上述功能代码时,需要通过“Thonny”工具将必备的bsp文件拷贝到pico板中,才能正常调用封装好的库,否则运行时会报找不到相应的库。

七、遇到的主要难题

         经过多次调试、检测,发现虽然通过增加延时时长、熄屏次数可以改善OLED残留图像的现象,但这种消隐的做法以牺牲时长、刷屏频率为代价,影响代码的高效执行。

八、未来的计划

         经过此次的项目实践,了解了MicroPython的基本语法,以及Thonny工具的简要运用。对比C语言的开发,MicroPython语言显得很简易,无需详细得了解底层驱动过程。对于bsp板级支持py文件的实现,还有很多不解的地方,后续计划对MicroPython语言更深入理解,由于手头没有多余的LED模块,加上时间不是很充裕,所以只用到板上的单色LED指示灯作为模拟的单路交通灯,如果后续条件允许,可以考虑做多路十字交通灯控制程序。

附件下载
TrafficCode.zip
团队介绍
本人有多年的嵌入式软件开发的工作经验,一直接触的是基于C语言的开发,从接触51单片机到Arm Cortex-M7,感觉微控制处理器性能越来越强大,C语言开发很贴近底层。得知此次使用Step Pico是基于MicroPython语言开发的,想借此机会敲开进入Python语言开发的大门,毕竟诸多智能终端产品都是基于Python语言开发的。
团队成员
yinwuqing
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号