基于STEP Pico的嵌入式平台的交通灯控制器
本项目为2023年寒假在家练项目,使用了硬禾学堂官方提供的STEP Pico树莓派单片机以及拓展板,使用Micropython编程,实现控制拓展版上8个WS2812bRGB灯以及SSD1306oled显示屏。
标签
嵌入式系统
显示
2023寒假在家练
collei
更新2023-03-29
北京理工大学
297

内容介绍

2023寒假在家一起练

基于Step Pico的嵌入式学习平台

项目名称:制作一个交通灯控制器

平台: 基于Step Pico的嵌入式平台

姓名: 赵鸿烨

1 项目要求

  • 完成交通灯的模拟:能够控制扩展版上12个WS2818B RGB三色灯实现自动定时切换颜色,并且在程序中设置接口以便于改变每种信号灯的持续时间。
  • 完成行人按钮功能:当K1或K2任意按键按下时,将交通灯立即切换为红灯,且该红灯的持续时间较默认时间更长。
  • 时间显示:通过SSD1306 OLED显示屏显示交通灯的倒计时。

2 完成的功能

2.1 交通灯模拟以及时间显示

连接电源,即实现交通灯的模拟。

c0f1d9f513920b2d1795811e9032280135ee1420ded60a80de99171f76759db9487dc3051024c7bb4615d774112fb

默认设置红灯持续时间为10s,绿灯为7s,黄灯为2s。当绿灯进入最后2s时,LED灯会闪烁。

2.2 行人按钮功能

按下任意按键后,指示灯会立即切换为红灯,且红灯持续时间设置为20s。之后若不再按下按钮,则红灯持续时间会恢复至10s。

Z

3 硬件介绍

3.1 Step Pico嵌入式开发板

Step Pico是一种小型、便携式的计算机,由Raspberry Pi和Step社区开发。它是一种基于ARM架构的计算机,可运行Linux操作系统。Step Pico具有小巧,功耗低,价格低,可扩展性强的特点。Step Pico也是一种开放源代码平台,可以通过MicroPython,C/C++等编程语言进行编程。由于它的小巧便携和低功耗特性,Step Pico被广泛用于物联网、嵌入式系统、机器人、教育和科研等领域。

Step Pico采用Raspberry Pi官方自主研发的RP2040微控制器芯片,运行频率高达133MHz,内置264KB SRAM和2MB flash,还提供多大26个多功能的GPIO引脚。通过将Step Pico平台与硬禾学堂设计的扩展版相结合,能够极大程度的扩展芯片的外部电路,简化编程,以便实现更多的功能。

3.2 WS2818B

WS2812B是三通道LED驱动控制专用电路,可支持多个芯片级联。芯片在上电复位后,DIN端接受从Step Pico微控制器传输的数据。首先传入的24bit数据被第一个芯片提取后,送入芯片内部的数据锁存器,剩余数据经内部整形处理电路通过Dout端口输出至下一个像素点。芯片内部的数据锁存器会根据所接收到的24bit数据,向所控制的三颗LED灯珠发送不同占空比的PWM信号,通过更改24bit的数据,可以控制每颗LED灯珠所显示的颜色。

WS2812B的数据协议采用单线归零码的通讯方式。其中0码,1码和RES码的波形如下:

GLD0JgNmxQDVLQu6io4F2v8FWwiCfbJXMKcAAAAASUVORK5CYII=

T0H

0码高电平时间

220ns-380ns

T0L

0码低电平时间

580ns-1.6us

T1H

1码高电平时间

580ns-1.6us

T1L

1码低电平时间

220ns-380ns

RES

帧单位

280us以上

24bit数据帧结构:

ufim3bUAAAAASUVORK5CYII=

采用MSB形式,以RGB顺序发送数据。

3.3 SSD1306

SSD1306是一款单片CMOS OLED驱动芯片,常用来驱动128*64分辨率的OLED显示屏。它由128个段和64个公共部分组成。

SSD1306内置对比度控制,显示RAM以及振荡器,减少了外部组件和功耗,可通过SPI或I2C总线与微处理器进行通信。SSD1306的内部结构图如下图所示:

XjCUD9huiWoAAAAASUVORK5CYII=

拓展版上的显示屏使用SPI总线与Raspberry Pi进行连接。数据的写入时序如下图所示:

CbqHv11Vf7vxtCCCGETiSiIIQwWSjgdX6EntXp9BFCCCF0MlX1v2s1915JvrhGAAAAAElFTkSuQmCC

在SCL的每个上升沿,SDA上的数据以MSB的形式以为到八位寄存器中,每八个时钟周期对D/C#进行一次采样,根据结果将图形写入GDDRAM中。之后SDA的数据将被写入GDDRAM,控制OLED显示屏。

4 实现思路

  • 使用定时器,通过中断控制LED灯的切换和OLED显示屏的数字切换;
  • 通过中断实现按键控制指示灯;
  • 使用ws2812B库函数对LED灯的颜色进行控制
  • 使用SSD1306库函数对OLED屏幕进行显示控制,并编写字库脚本以提升显示效果。

5 程序框图

wNuBs4Ol794CQAAAABJRU5ErkJggg==

6 主要代码片段:

6.1 模n计数器

def timer_mod_n(n):  
    global TIMER  
    if TIMER != n:  
        TIMER = TIMER + 1  
    else:  
        TIMER = 0  

输入参数n为计数器的模。

在主定时器发送中断请求时执行,其中全局变量TIMER用来控制LED灯的颜色和OLED的显示。

该函数通过MicroPython提供的软件定时器回调,软件定时器周期设置为0.5s,即该函数每0.5s调用一次。因此,TIMER变量的周期为0.5n秒。

6.2 颜色控制

def Color_Ctrl(red_t,green_t,yellow_t):  
    global color  
    global TIMER  
    red_t = red_t*2  
    green_t = green_t*2  
    yellow_t = yellow_t*2  
    if TIMER == red_t:  
        ws2812b.on_all(green)  
        color = "green"  
    elif TIMER == red_t+green_t-4:  
        ws2812b.off_all()  
        color = "green"  
    elif TIMER == red_t+green_t-3:  
        ws2812b.on_all(green)  
    elif TIMER == red_t+green_t-2:  
        ws2812b.off_all()  
    elif TIMER == red_t+green_t-1:  
        ws2812b.on_all(green)  
    elif TIMER == red_t+green_t:  
        ws2812b.on_all(yellow)  
        color = "yellow"  
    elif TIMER <= 0:  
        ws2812b.on_all(red)  
        color = "red"

输入red_t,green_t,yellow_t为红,绿,黄灯的持续时间,单位为秒,默认设置为红灯10s,绿灯7s,黄灯2s。

根据全局变量TIMER的值控制交通灯的颜色。

6.3 显示控制

def disp_time(timer):  
    if timer%2 != 0:  
        timer = timer + 1  
    else:  
        pass  
                 
    if color == "red":  
        time = -timer + 20  
    elif color == "green":  
        time = -timer + 34  
    elif color == "yellow":  
        time = -timer + 38  
    time = time / 2  
    timer_bit = time % 10  
    timer_dic = time // 10  
    screen1 = screen(timer_dic,timer_bit)  
    screen1.display()  

控制OLED屏幕显示当前交通灯的倒计时。其中screen为文件“image.py”中定义的类,用来控制OLED屏幕显示。字库存放于“ziku.py”文件中。

6.4 按键中断函数

def button_callback():  
    global TIMER  
    global color  
    TIMER = -21       #红灯延长10s  
    color = "red"  
    ws2812b.on_all(red)  
    screen1 = screen(2,0)  
    screen1.display()  

在按键按下时触发,作用为:

  • 立即将LED切换为红色
  • 在默认红灯持续时间的基础上,延长10s
  • 显示屏显示数值“20”

注:由于红灯默认时长为10s,按下按键后又延长10s,因此设置显示屏显示20s,当修改红灯默认持续时间和红灯延长时间后,应对应修改显示数值。

7 遇到的困难及解决方法

最初的程序架构为双线程架构,其中一个线程控制交通灯,另一线程控制OLED刷新。在烧录后发现,两线程的时钟不能严格对齐,容易出现OLED显示屏和LED灯变化不同步的问题,且由于单片机执行LED刷新或OLED显示屏刷新函数的时间未知,使用sleep函数不能精确定时。随时间推移,会产生计时不准确的问题。为解决这一问题,之后在程序中引入定时器,通过定时器发送定时信号,实现每隔0.5s刷新一次显示屏和LED灯,从而实现两者的同步。

附件下载

项目代码.zip

团队介绍

北京理工大学 赵鸿烨
团队成员
collei

评论

0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号