一、项目介绍
基于树莓派pico的嵌入式系统学习平台,具有能耗比高,外设丰富,编程语言microPython易于使用等特点,利于学习嵌入式系统的工作原理和应用。本项目通过此树莓派pico平台,制作一个反应测试器。
一、项目介绍
本项目基于树莓派pico的嵌入式系统学习平台,其具有能耗比高,外设丰富,编程语言microPython易于使用等特点,利于学习嵌入式系统的工作原理和应用。通过树莓派pico为控制核心,用microPython语言编程制作一个反应测试器。反应测试器功能为随机点亮树莓派pico扩展板上的一个LED,按下扩展板上的一个按键,能够在扩展板上的OLED屏幕上显示从灯亮到按键之间的时间。
二、设计思路
1.随机点亮一个LED:树莓派pico中有四种不同颜色的LED,分别是red,yellow,blue,green。每次测试需要随机点亮一个LED,于是在程序中设置随机数,通过产生的随机数来控制每次测试点亮的LED,从而实现随机点亮不同颜色的LED。
2.在随机时间点亮LED:反应测试中,LED等点亮的时间也要是随机的,程序中可以通过在设定范围内产生的随机数来作为LED在测试开始后随机点亮的时间,由此可以实现LED灯在随机时间点亮。
3.计算LED从点亮到接收到按键之间的时间差:程序中调用time.ticks_ms()来计时,(time.ticks_ms()返回不断递增的毫秒计数器中的数值)。timer_start记录LED灯点亮时的数值,在按键后返回time.ticks_ms()与timer_start的差值,即得LED从点亮到接收到按键之间的时间差。
4.实现反复测试:添加一个按键作为每次测试的开关,按下按键程序开始运行,进行一次测试,再按下按键,程序刷新,进行新一次的测量。
三、软件流程图
四、软件与硬件
1.软件:thonny
本项目使用的开发软件是thonny,作为官方推荐使用的开发软件,thonny的调试器是专为学习和教学编程而设计的,具有页面简洁,基础功能齐全,简单易上手,对初学者十分友好的特点。软件操作简单,在使用过程中的确上手很快。
2.硬件:基于树莓派Pico的嵌入式系统学习平台
本项目使用的硬件是基于树莓派Pico的嵌入式系统学习平台,平台包括硬禾版本树莓派pico核心模块和树莓派pico扩展板。树莓派PICO核心板块是一款低成本,高性能的微控制器开发板,具有灵活数字接口,硬件上采用Raspberry Pi官方自主研发的RP2040微控制器芯片,搭载了ARM CortexM0+双核处理器,高达133赫兹的运行频率,内置了264KB SRAM和2 MB 闪存,还板载有多达26个多功能的GPIO引脚。硬件开发软件可以选择C语言/C++SDK,或者使用microPython,可以快速入门实现开发。
核心板引脚图
五、实现的功能及图片展示
本程序代码实现了反应测试器要求实现的全部功能。按下按键k2开始反应测试,测试器在2到5秒的随机时间内会随即点亮红、蓝、黄、绿四个LED中的随机一个,灯亮程序开始计时,受试者在接收到灯亮信号后按下按键k1,k1按下瞬间记录时间,即为受试者的反应时间,并在OLED上显示。
六、主要代码片段及说明
#需引用的文件
import time
import ws2812b
from button import k1,k2
from board import pin_cfg
from led import r,y,g,b
from oled import oled
from button import button
from machine import Pin
import random
#程序主循环,引入按键K2设置为启动按键,控制循环进行,按下k2按键视为一次测试循环,继续按键可以实现多次重复测试
def k2_callback(pin):
global timer_start
timer_start=0;
#产生一个随机数,随机点亮一个LED
a=random.uniform(1,5)
bb=int(a);
y.off();
r.off();
g.off();
b.off();
time.sleep(random.uniform(2,5)); #产生2到5范围内随机数,控制点亮LED的时间
if bb==1: #随机点亮LED灯
y.on();
if bb==2:
r.on();
if bb==3:
g.on();
if bb==4:
b.on();
timer_start=time.ticks_ms(); #计时开始
k2=button(pin_cfg.k2,k2_callback,trigger=Pin.IRQ_FALLING)
#按键k1功能,按下k1按键,计算出LED灯点亮到k1按键按下的反应时间,并将结果输出在oled屏幕上
def k1_callback(pin):
global timer_start
time_reaction=time.ticks_ms()-timer_start #通过计算差值得到反应时间
clear(oled);
print_result(str(time_reaction)+"ms") #在OLED屏幕上输出反应时间
k1=button(pin_cfg.k1,k1_callback,trigger=Pin.IRQ_FALLING)
七、遇到的主要难题及解决方法
本实验在平台赠送的microPython编程课程的指导下进行的比较顺利,课程讲述的比较详细,能让我很快上手开始项目,在进行中还是遇到一些问题。首先是反应测试器程序只能进行一次测试,不能实现重复多次测试,经过思考我想到了采用循环的方法,引入k2按键控制程序循环运行,按下k2,程序数据重置,循环运行一次,实现一次反应测试,经过检验,这个方法是可行的,如下:
def k2_callback(pin):
global timer_start
timer_start=0;
#产生一个随机数,随机点亮一个LED
a=random.uniform(1,5)
bb=int(a);
y.off();
r.off();
g.off();
b.off();
time.sleep(random.uniform(2,5)); #产生2到5范围内随机数,控制点亮LED的时间
if bb==1:
y.on();
if bb==2:
r.on();
if bb==3:
g.on();
if bb==4:
b.on();
timer_start=time.ticks_ms(); #计时开始
k2=button(pin_cfg.k2,k2_callback,trigger=Pin.IRQ_FALLING)
可是调试过程中又遇到一个问题,那就是虽然实现重复测量,但忽略了OLED显示的重置,于是测试中新的反应时间数据叠加在上次显示数据上,于是数据读不出来。意识到新的测试开始先前的OLED输出应该要清空,查阅资料,找到了一个解决方法。定义一个函数:
def clear(self):
self.fill(0)
OLED输出新数据前先调用该函数清除先前数据在输出,问题顺利解决。
八、未来的计划或建议
本项目总体比较简单,最后完成的效果也基本实现了要求,但这只是嵌入式系统入门级,未来还想继续深入学习,尝试完成其他项目,强化自己的microPython编程能力和对嵌入式系统的理解,希望在学习中继续强化自己的动手实践能力。