基于STEP Pico制作反应测试器
反应测试器是一种心理学实验设备,用于测试被试者的反应时间。本项目使用的是STEP Pico开发板,通过控制板上的LED和按键,实现了一个简单的反应测试器。
标签
嵌入式系统
显示
接口
2023寒假在家练
三十三连的火夫
更新2023-03-29
北京理工大学
390

项目介绍

反应测试器是一种心理学实验设备,用于测试被试者的反应时间。本项目使用的是STEP Pico开发板,通过控制板上的LED和按键,实现了一个简单的反应测试器。

设计思路

本项目的设计思路如下:

  1. 使用MicroPython语言编写代码,通过软件生成随机数,控制板上的LED随机点亮。
  2. 当LED点亮后,被试者按下按键,程序计算从点亮灯到接收到按键之间的时间差,并将时间差通过USB显示在PC上,也可以将OLED用起来,在OLED上显示时间信息。
  3. 程序允许被试者多次测试。

软件流程图

Fs32-OC7wueCz7xhsM47_ZQpltt6

硬件介绍

本项目采用了STEP Pico开发板、LED和按键。其中,LED连接到Pico的GP25引脚,按键连接到Pico的GP14引脚。此外,用户还可以通过USB连接将计时结果发送到PC上,或使用OLED屏幕显示计时结果。

STEP Pico是一款高性能、低成本的微控制器开发板,完全兼容Raspberry Pi Pico,并具备灵活的数字接口。它搭载了由Raspberry Pi官方自主研发的RP2040微控制器芯片,内置双核ARM Cortex M0+处理器,最高运行频率达133MHz,还有264KB SRAM和2MB闪存,同时板载了多达26个多功能GPIO引脚。

在软件方面,用户可以选择使用树莓派提供的C/C++ SDK或使用MicroPython进行开发。完善的开发资料和教程可以让开发者快速上手,并将其嵌入到本项目中。

实现的功能及图片展示

本项目实现了以下功能:

  1. 随机点亮板上的一个LED。
  2. 在显示屏上显示出从灯亮到按键之间的时间。
  3. 允许被测试者多次测试。

下面是本项目的图片展示。

图1:烧录完成后的STEP Pico开发板

Fi9edJQE33DFar2PZ2A6HRW-4XGW

图2:按下k2按钮后反应测试开始

Fhw00LXbtWKk6L4wZFKF85Lzx1hL

图3:随机LED亮,计时开始

FrS7J0arD8x51T2reH3CkiESnFKW

图4:显示反应时间并等待新一轮测试

FuOa0A84ApaKJI1iZTld8CzPO2aJ

主要代码片段及说明

导入需要使用的模块和库。

from button import k1, k2 # 导入按钮模块,使用k1作为反应检测按钮,k2作为开始按钮
from oled import oled # 导入oled模块,用于显示信息
import time
import ws2812b # 导入ws2812b模块,用于控制LED灯
import random # 导入random模块,用于生成随机数

定义变量用于记录测试状态、随机时间、反应时间、起始时间、结束时间和随机点亮的LED灯编号。

random_time = 0 # 用于记录随机时间
react_time = 0 # 用于记录反应时间
start_time = 0 # 用于记录起始时间
end_time = 0 # 用于记录结束时间
random_led = 0 # 用于记录随机点亮的LED灯编号

清空屏幕并在oled上显示提示信息。

oled.fill(0) # 清空屏幕
oled.show() # 显示空屏
oled.text("Press k2 to Run", 3, 20) # 在屏幕上显示提示信息
oled.text("Reaction Test", 12, 40)
oled.show() # 显示提示信息
ws2812b.off_all() # 关闭所有LED灯

进入循环等待用户按下k2按钮开始测试。

while True: # 进入循环
    if k2.value() and not testing: # 如果按下开始按钮并且当前没有进行测试
        testing = True # 开始进行反应测试
        # 详细代码在此省略

如果用户按下k2按钮,则程序会随机生成等待时间和随机点亮一个LED灯,并在oled上显示“Ready!”提示信息,等待随机时间后开始测试。

        oled.fill(0) # 清空屏幕
        oled.show() # 显示空屏
        random_time = random.uniform(2, 5) # 随机生成等待时间
        random_led = int(random.uniform(0, 12)) # 随机点亮一个LED灯
        oled.text("Ready!", 40, 28) # 显示提示信息
        oled.show() # 显示提示信息
        time.sleep(random_time) # 等待随机时间
        start_time = time.ticks_ms() # 记录起始时间戳

点亮一个LED灯并在oled上显示“Press!”提示信息,程序会记录下开始时间戳。

        if k1.value(): # 如果提前按下了反应检测按钮
            start_time = time.ticks_ms() # 更新起始时间戳
        oled.fill(0) # 清空屏幕
        oled.show() # 显示空屏
        oled.text("Press!", 40, 28) # 显示提示信息
        oled.show() # 显示提示信息
        ws2812b.on(random_led) # 点亮一个LED灯

进入循环等待用户按下k1按钮,如果用户按下了k1按钮则记录下结束时间戳,并计算反应时间,否则如果时间超时则在oled上显示“Timeout”提示信息。

        while not end_time and time.ticks_ms() - start_time < timeout: # 进入循环,如果反应时间未记录并且时间未超时
            if k1.value(): # 如果检测到反应检测按钮被按下
                end_time = time.ticks_ms() # 记录结束时间戳
                ws2812b.off(random_led) # 关闭点亮的LED灯
        if end_time is None: # 如果时间超时
            ws2812b.off(random_led) # 关闭点亮的LED灯
            oled.fill(0)
            oled.show()
            oled.text("Timeout", 40, 28) # 在oled上显示超时信息
            oled.show()
            time.sleep(1) # 等待1秒后重置oled屏幕

显示反应时间并在oled上显示开始下一轮测试的提示信息,允许用户重新开始测试。

        else:
            reaction_time = end_time - start_time # 计算反应时间
            oled.fill(0)
            oled.show()
            oled.text("Reaction Time", 12, 10)
            oled.text('{:3.3f}s'.format(reaction_time/1000), 12, 30) # 在oled上显示反应时间,以及开始下一轮测试的提示
            oled.text("k2--Retry", 12, 50)
            oled.show()
            print('Reaction Time: {:.3f}s'.format(reaction_time/1000)) # 将时间差通过USB显示在PC上
        testing = False # 结束反应测试,允许重新开始

遇到的主要难题及解决方法

  1. 如何控制LED的点亮和熄灭?

在本项目中,LED是用来模拟实验中的刺激信号,因此需要精确控制LED的点亮和熄灭时间。为了实现这一点,我选择了一个名为ws2812b的LED驱动库。该库可以让我轻松地控制单个LED的亮度和颜色,并且可以控制多个LED的同步点亮和熄灭。在代码中,我使用ws2812b库的off()和on()函数来控制LED的熄灭和点亮。

  1. 如何计算反应时间?

在本项目中,我需要测量从LED点亮到被测试者按下按钮的时间差,也就是反应时间。为了实现这一点,我使用了板载时钟模块来计算时间。具体来说,我在点亮LED后记录当前的时间戳,并在检测到按键按下时再记录一个时间戳。然后,我可以通过这两个时间戳的差值来计算反应时间。

  1. 如何控制时间的精度?

在本项目中,时间的精度非常重要,因为我需要精确地测量反应时间。为了实现这一点,我使用了板载时钟模块来计算时间,该模块的精度为毫秒级。在程序中,我还使用了time.sleep()函数来控制程序执行的时间,以确保LED点亮和按键检测发生的时间是在规定的时间范围内。

  1. 如何控制随机数的生成?

在本项目中,我需要随机选择LED点亮的时间和LED的位置。为了实现这一点,我使用了Python的内置random库来生成随机数。具体来说,我使用random.uniform()函数来生成指定范围内的随机浮点数,然后将其转换为整数来选择LED的位置。

  1. 如何控制反应测试的进行和结束?

在本项目中,我需要控制反应测试的进行和结束。具体来说,我需要在按下开始按钮后等待随机时间,然后点亮LED,等待被测试者按下按钮,计算反应时间,然后在显示屏上显示结果。在程序中,我使用了一个testing变量来控制反应测试的进行和结束。当testing为True时,反应测试正在进行中。当testing为False时,反应测试已经结束。

  1. 如何防止提早按下k1导致记录的反应时间为0?

在本项目的实现中,一项主要难题是如何防止k1提前按下而导致反应时间记录为0的错误。这是因为当LED点亮时,被测试者可能会提前按下按键k1,导致计时器在按下k1之前就已经停止了,这样就会记录一个0的反应时间,影响测试结果的准确性。

为了解决这个问题,我添加了如下逻辑:在按下k2之后,记录当前的时间戳为起始时间戳,然后在等待按下反应按钮之前,判断k1是否已经被按下,如果已经被按下,就将起始时间戳更新为当前时间戳,这样即使提前按下k1,记录的反应时间也会正确计算。

这个方法可以有效地避免k1提前按下导致反应时间记录为0的问题,同时也能够保证测试的准确性和可靠性。在实际的测试中,我也进行了多次验证,证明这个方法是有效的。

未来的计划或建议

对于未来的计划或建议,可以考虑从以下几个方面展开:

功能增强:可以考虑在现有的基础上增加一些新的功能,比如添加多个LED,实现更复杂的闪烁模式;或者增加多个按键,实现不同的控制方式等。

硬件优化:可以考虑对硬件进行一些优化,比如使用更高性能的处理器、更高精度的传感器等,提高设备的整体性能和使用体验。

软件升级:可以考虑对软件进行升级,比如添加更多的控制指令、优化程序代码,提高设备的响应速度和稳定性。

设备集成:可以考虑将本项目与其他设备进行集成,比如与智能家居设备进行联动,实现更智能化的控制方式等。

用户体验:可以考虑从用户体验的角度出发,对设备进行一些改进,比如外观设计、人机交互界面等,提高用户的使用感受。

综上所述,本项目在未来的发展中,可以从硬件、软件、功能、集成、用户体验等多个方面进行改进,以提高设备的整体性能和用户满意度。

附件下载
附件.rar
STEP Pico反应测试器代码文件
团队介绍
北京理工大学电子信息工程专业学生-吴松凌
团队成员
三十三连的火夫
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号