基于STEP Pico的嵌入式系统学习平台
制作一个交通灯控制器
具体要求:仿真马路上的交通灯的工作状态切换,利用板上的红、黄、绿三种颜色的LED显示道路状态的切换,行人按键时,具有优先功能
实现方式:利用板上的3个不同颜色的LED模拟交通灯,程序会轮流切换三个灯的状态,并根据按键的输入(中断或查询机制)调整交通灯的切换
一:配置环境
- Thonny:
作为官方推荐的开发软件,Thonny页面简洁,基础功能齐全,简单易上手,非常适合初学者。
- 硬禾学堂树莓派pico平台:
硬禾学堂为“寒假一起练”活动提供一个嵌入式系统平台,该平台包括硬禾版本树莓派Pico核心模块-STEP Pico以及树莓派Pico扩展板。
核心模块STEP Pico使用了树莓派公司自行设计研发的rp2040微控制器芯片,拥有133MHz运行频率、264KB SRAM以及2MB的闪存,支持C/C++和Python语言。而扩展板则基于核心模块的设计方向和预期功能装配了2个输入按键、4个单色LED、12个WS2812B RGB三色灯、姿态传感器、128*64 OLED显示屏、蜂鸣器、可调电位计(用于电压表)、音频信号输入(用于示波器)、8位R-2R电阻网络构成的DAC(用于DDS信号发生器)等众多配件,可以用于实现十分丰富的扩展功能项目。
二:需求分析:
1、使用扩展板上的LED灯发出红黄绿三色光来模拟交通灯,需要使用三个不同颜色的LED灯,则需要先对该扩展配件进行配置。
2、项目要求实现行人按键优先功能,即需要通过按键的输入来调整交通灯的切换,则需要对输入按键进行配置。
3、编程控制LED灯的颜色变化、持续时间、颜色顺序来模拟交通灯的基础功能。然后加入输入按键对持续时间的控制,增加行人调整功能。
完成的功能及达到的实现结果如下图:
通过使用树莓派PICO扩展板和硬禾版本树莓派PICO核心模块- STEP PICO模拟马路上的红黄绿三色交通灯的相互切换的工作状态,通过编程使得扩展版上的红黄绿LED灯光进行变换。开始时红灯常亮,持续五秒钟后,灯光颜色转变为黄灯,黄灯状态持续两秒钟后,灯光颜色转变为绿灯,再经过两秒钟的黄灯提醒,最后恢复红灯状态,从而实现重复。
具体图示
如图,开始时,给电路板通电,运行程序,对芯片进行初始化,红色LED灯常量
经过5秒钟倒计时后红灯熄灭,黄灯亮起,持续2秒钟
再经过2秒钟后黄灯熄灭,转换为绿灯持续5秒钟
最后经过5秒钟倒计时后绿灯熄灭,黄灯亮起,持续2秒钟
按下k1,k2按钮可以延长红灯绿灯的持续时间。
三:流程图:
四:程序实现:
该项目使用了STEP Pico开发板,这是一款高性能、低成本的微控制器开发板,具有灵活的数字接口,完全兼容Raspberry Pi Pico。该开发板与LED和按键组合在一起,实现了一个交通灯控制器的功能,用户可以通过按下按键,延长红灯或者绿灯的常亮时间。
硬件上,STEP Pico开发板采用Raspberry Pi官方自主研发的RP2040微控制器芯片,搭载了ARM Cortex M0+双核处理器,高达133MHz的运行频率,内置了264KB SRAM和2MB闪存,还板载有多达26个多功能的GPIO引脚。
在软件方面,开发人员可以选择使用树莓派提供的C/C++SDK或者使用Micropython进行开发且配套有完善的开发资料教程,可方便快速入门开发并嵌入到产品中。该项目展示了STEP Pico开发板在物联网和嵌入式开发等领域中的应用前景。
程序均使用Micropython语言编写,该语言相对于Python语言更加易于上手,对初学者很友好。
- 代码解析
程序调用了库中的board.py、button.py文件对扩展板上的LED灯、输入按键进行基础配置,实现pin与配件的对应。
库中的board.py文件如下
### board.py --- eetree micropython training board configuration.
class pin_cfg:
yellow_led = 20
blue_led = 21
green_led = 22
red_led = 26
buzzer = 19
mic = 27
i2c0_scl = 17
i2c0_sda = 16
i2c1_scl = 15
i2c1_sda = 14
spi1_mosi = 11
spi1_sck = 10
spi1_dc = 9
spi1_rstn = 8
spi1_cs = 29
adc0 = 26
adc1 = 27
k1 = 12
k2 = 13
pot = 28
库中的button.py文件如下
### botton.py --- eetree micropython training board configuration.
import time
from board import pin_cfg
from machine import Pin
class button:
def __init__(self, pin, callback=None, trigger=Pin.IRQ_RISING, min_ago=200):
#print("button init")
self.callback = callback
self.min_ago = min_ago
self._next_call = time.ticks_add(time.ticks_ms(), self.min_ago)
self.pin = Pin(pin, Pin.IN, Pin.PULL_UP)
self.pin.irq(trigger=trigger, handler=self.debounce_handler)
self._is_pressed = False
def call_callback(self, pin):
#print("call_callback")
self._is_pressed = True
if self.callback is not None:
self.callback(pin)
def debounce_handler(self, pin):
#print("debounce")
if time.ticks_diff(time.ticks_ms(), self._next_call) > 0:
self._next_call = time.ticks_add(time.ticks_ms(), self.min_ago)
self.call_callback(pin)
def value(self):
p = self._is_pressed
self._is_pressed = False
return p
k1 = button(pin_cfg.k1)
k2 = button(pin_cfg.k2)
- 初始化配置
import time
from button import k1,k2,
from machine import PWM,Pin
from board import pin_cfg
###配置不同函数代表让三个不同颜色的LED灯按发光。然后根据交通灯的工作方式编写“红—黄—绿—黄”的循环语句,并使不同颜色持续的时间不同。
###配置三个LED灯
r = Pin(pin_cfg.red_led,Pin.OUT)
y = Pin(pin_cfg.yellow_led,Pin.OUT)
g = Pin(pin_cfg.green_led,Pin.OUT)
###编写循环,红灯亮5秒、黄灯亮2秒、绿灯亮5秒、黄灯亮2秒
while True:
r.value(1)
time.sleep(5)
###编写程序,k1按键控制,当红灯亮时,按下按键,红灯常亮时间延长 3秒
if k1.value() == True:
r.value(1)
time.sleep(3)
r.value(0)
pwm.deinit()
r.value(0)
y.value(1)
time.sleep(2)
y.value(0)
g.value(1)
time.sleep(5)
###编写程序,k2按键控制,当绿灯亮时,按下按键,绿灯常亮时间延长 3秒
if k2.value() == True:
g.value(1)
time.sleep(3)
g.value(0)
pwm.deinit()
g.value(0)
y.value(1)
time.sleep(2)
y.value(0)
五:遇到的主要难题及解决方法:
主要难题:
当循环中如果只写入亮灯将会导致亮灯效果不明显,或只出现灯光闪烁
解决方法:
通过使用时间函数(time),利用内置时序实现亮灯时变化暂停,从而保持LED亮处于常亮状态。
六:未来的计划建议:
该项目已经成功实现了简易示波器和信号发生器的功能,并达到了预期指标。然而通过利用扩展板上的其它硬件,还有可以改进提升的空间:
例如可以在扩展板上的显示屏制作行人的动画,在绿灯时播放行人行走的运动画面,在红灯时播放行人停止行动的画面。