基于STEP Pico树莓派板卡完成一个简单的反应测试器
本次项目中我使用Step Pico树莓派板卡,结合老师给出的python代码和库文件,成功制作出了一个具有测试反应时间功能,并可以多次重新测试并显示信息的反应测试器
标签
嵌入式系统
测试
显示
2023寒假在家练
wjm
更新2023-03-29
北京理工大学
376

1 硬件平台

STEP Pico是一款低成本,高性能的微控制器开发板,具有灵活数字接口(完全兼容Raspberry Pi Pico)。硬件上,采用Raspberry Pi官方自主研发的RP2040微控制器芯片,搭载了ARM Cortex MO+双核处理器,高达133MHz的运行频率,内置了264KB SRAM和2MB闪存,还板载有多达26个多功能的GPIO引脚。软件上,可选择树莓派提供的C/C++SDK,或者使用MicroPvthon进行开发且配套有完善的开发资料教程,可方便快速入门开发并嵌入到产品中。

2 项目要求

利用Step Pico板卡制作一个反应测试器:随机点亮板上的一个LED,在LED亮起后马上按下板上的k1按键,并在显示屏上和pc端上显示出从灯亮到按键之间的所用时间,这是心理学上的一个重要实验。

3 计划实现的功能

最基本的功能为:在测试开始后随机等待2-5秒,然后亮起12个LED灯中随机的一个,灯亮起后按下k1便可在oled和pc端上同时显示出被测试者从灯亮起到按下按键所用的反应时间;

拓展功能为:在一次测试结束后,按下k2按键便可重新开始新一轮的测试,并同时在oled和pc端上显示该次测试的次数。

4 功能实现的具体方式和流程

对于基本功能,我设计的程序流程和使用的方式如下:

4.1随机点亮LED

在程序启动后,首先产生两个随机数,第一个随机数n用来决定被点亮的LED的序号,而第二个随机数用来控制测试开始后过多久时间来点亮板上的LED。该部分代码如下所示:

while True:
    n=random.uniform(1,12)
    for i in range(13):
        if(n-i<0.5):
            n=i
            break
    ws2812b.off_all()
    time.sleep(random.uniform(2,5))
    ws2812b.on(n, color = "#000010")

其中for循环用来对随机数n取整,因为random.uniform函数产生的随机数并非整数,而ws2812b.on函数所需要的LED序号参数为整数。

4.2按下k1后测试反应时间

在LED被点亮之后,我们先记录一次当前时间:

    timer_start = time.ticks_ms()

随后进入time.sleep中等待k1的按下:

    for i in range(400):
        if(a==1):
            break
        time.sleep(0.25)
    a = 0

上面这段代码用于等待k1按下,总计等100s,若100s后无反应则重新进入主循环开始新的测试。其中a的作用将在下文进行解释。

若我们在这100s内按下k1,则k1会执行以下代码:

def k1_callback(pin):
    global timer_start
    global flag
    oled.fill(0)
    timer_reaction = time.ticks_ms() - timer_start 
    flag = 0
    print_result("Time: " + str(timer_reaction) + "ms")
    time.sleep(1)
    flag = 1
    print_result("Again?")
k1 = button(pin_cfg.k1, k1_callback, trigger=Pin.IRQ_FALLING)

程序将再次记录一次时间,该次时间便是按下按键时的时刻,用该时刻减去之前LED灯亮起时记录的时刻,我们便可以得出被测试者从灯亮起到按下按键所用的反应时间。对于反应时间,我们使用老师所给的print_result函数将其同时显示在oled和pc上。从显示结果起过1s后,程序将再次利用print_result函数在oled和pc端上显示“again?”字样,询问被测试者是否再来一次测试。对于print_result函数我做了一点修改,利用一个变量flag来决定字符在oled上显示的位置,从而使反应时间结果和“again?”字符上下错位显示而不会混叠,如下所示:

def print_result(msg):
    print(msg)
    if(flag == 0):
        oled.text(msg,0,26)
    if(flag == 1):
        oled.text(msg,0,42)
    oled.show()

FgJA18ZvR_dHs36DPNrymg-y3TQD

4.3 按下k2后进行新一轮测试

对于k2,我设置了以下一段程序,其将会在按下k2后执行:

def k2_callback(pin):
    global a
    global b
    global flag
    a = 1
    b = b+1
    flag = 0
    oled.fill(0)
    print_result("Test " + str(b))
k2 = button(pin_cfg.k2, k2_callback, trigger=Pin.IRQ_FALLING)

该代码的主要思路为:4.1中展示的主循环函数末端的for循环在每次循环时都会对a的值进行一次检测,若a值为1则跳出循环。而按下k2后,上面这段代码会将全局变量a的值置1,从而使该段for循环中0.25s的time.sleep结束后跳出循环,随后主循环将a重新归0,并开始新的一次主循环,也就是进行一次新的测试。此外,按下k2后会将初值为1的全局变量b的值加1,b的值用来在按下k2后在oled和pc端显示新一轮测试的序号次数。。

4.4 程序运行流程综述

综上所述,在程序开始运行后等待2-5s后板卡上十二个LED会随机亮起一个,在LED亮起后若测试者按下k1,则显示反应时间;若LED亮起后100s内无操作,则进行新一轮测试。在按下k1显示反应时间后,若我们再按下k2,则可跳过100s的等待时间,直接进行新一轮的测试,同时显示测试的序号次数。

程序整体流程框图如下:

FsXLFLRbqdXRtDJ4C2oVD0YdbfdI

5 遇到的问题与难点

在本次项目中,我遇到的难点是在oled屏幕上显示字符后,第二次再显示字符会与第一次显示的字符混叠起来,导致根本看不清显示出来的是什么。对于这个问题,我的解决方法是利用百度到的一个函数:oled.fill(0),该函数可以填满oled屏幕,括号内的值表示填满的颜色,若为0,则用黑色填满屏幕,也就是与清空屏幕一样的效果。利用此函数,我顺利解决了该难点。

6 未来的计划

在本次项目中,我第一次接触到了python语言和树莓派板卡,所做的项目也比较简单,但是我也从中学到了很多东西,不管是硬件方面还是软件方面,我都获取了很多之前从未学习过的新知识,这也为我打开了一扇新世界的大门。我计划在将来继续参与类似的项目,提升自己对硬件构造的认知,同时也可以提升自己的编程水平。

附件下载
main.py
该文件为我的项目的程序代码文件,在板卡上运行该程序便可实现反应测试器;该程序依赖于学习平台gitee所提供的几个库文件,如ws2812b.py、oled.py等等,因为超出数量限制,便不在此上传这几个库文件了
团队介绍
本人韦建明,是北京理工大学电子信息工程专业的一名大四本科生
团队成员
韦建明
来自北京理工大学,是电子信息工程专业的一名大四本科生
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号