用树莓派pico制作一个反应测试器
一、项目介绍
本项目属于电子森林“2023寒假在家一起练项目”中的一个分支。项目平台为基于STEP pico的嵌入式系统学习平台,项目内容为使用树莓派pico学习板制作一个反应测试器。
具体要求为:按下按键开始测试,某一时间范围内随机时刻点亮任意一颗LED,LED亮后第一时间按下板上一个按键,测量并显示灯亮与按键之间的时间,即为反应时间。这是心理学上一个重要的实验。本项目目标就是使用树莓派pico学习板制作一个这样的反应测试器,并使其尽可能完善。
二、设计思路
项目主要包含如下几个关键点:
1、点亮LED的随机时间的产生;
2、随机点亮某一颗LED,LED的选择;
3、关键时间的测量;
4、按键操作与学习板反应的对应。
结合上述关键问题,简述设计思路如下:
运行程序,检查显示状态,将所有显示(灯,oled屏幕)归零,显示开始界面;按键开始测试,计时开始;限定时间范围内某随机时刻,随机灯亮,记录灯亮时刻;随即按下反应按键,灯灭,记录按键时刻;计算并显示反应时间,提示按键开始下一次测试;形成循环,可以反复测试。
在具体的实现上,随机数我使用软件产生,利用每个RGB都有各自编号的特点,产生随机整数,使每个随机数都对应一个RGB灯,实现RGB的随机点亮;随机亮灯时间也使用软件产生,使用time库中的sleep控制开始按键k1按下到测试灯亮的随机时间;使用time库中的ticks_ms得到时间上较为精确的测量值;oled的使用则是参考支持库中的函数,通过对文字输出坐标的调整实现美观的显示输出。
三、流程框图
四、硬件介绍
本项目使用的硬件是基于树莓派pico的嵌入式系统学习平台,其可以通过C/C++以及MicroPython编程来学习嵌入式系统的工作原理和应用。本项目使用的语言为Micro Python。
平台硬件包括:树莓派Pico扩展板一块,硬禾版本Pico核心模块一块。
板卡硬件:
- 2个按键输入
- 4个单色LED
- 12个WS2812B RGB三色灯
- 1个姿态传感器
- 1个128*64 OLED显示屏
- 1个蜂鸣器
- 1个可调电位计(用于电压表)
- 1路音频信号输入(用于示波器)
- 8位R-2R电阻网络构成的DAC(用于DDS信号发生器)
本项目用到的有:2个按键输入,3个单色LED(红黄绿),12个ws2812bRGB灯,oled显示屏。
板卡功能及管脚映射图如下:
STEP Pico
STEP Pico是一款低成本高性能的微控制器开发板,具有灵活数字接口。硬件上采用树莓派官方研发的RP2040微控制器芯片,搭载了ARM Cortex M0+双核处理器,高达133MHz的运行频率,内置了264KB SRAM和2MB闪存,还板载有多达26个多功能GPIO引脚。
Pico核心模块引脚图如下:
五、功能展示
运行程序,加载开始界面。显示程序名字“Reaction Game”与操作提示:“请按下k1键,开始游戏”。
按照操作提示,按下k1按键,测试开始,进入等待状态,红灯亮,显示屏显示:“请等待···”。
随机RGB亮起,红色led熄灭,橘色led亮起,显示屏显示内容更换为“开始”。此时玩家看到RGB灯亮起,应按下k2按键,使灯光熄灭并记录反应时间。
按下k2,RGB熄灭,绿色灯亮,测试完成,oled屏幕显示本次测试时间与操作提示
按照操作提示,再次按下k1,开始下一轮测试
六、主要代码
程序主循环代码如下:
while True:
if k1.value():#检测到k1按下
oled.fill(0)
oled.show()#oled屏幕清空
rand_time = random.uniform(2, 5)#随机亮灯时间范围为2-5s
cs_led = int(random.uniform(0, 12))#为选灯数赋随机值
oled.text("waiting...", 12, 20)
oled.show()#操作提示文本
r_on()#红色led亮,等待测试开始
time.sleep(rand_time)#延长随机时间
oled.fill(0)
oled.show()
oled.text("start", 12, 20)
oled.show()#提示开始测试
ws2812b.on(cs_led)#点亮选灯数代表的一颗灯
y_on()#黄灯亮,测试进行中
start_time = time.ticks_ms()#记录亮灯用时
while True:
if k2.value():#检测k2按下
end_time = time.ticks_ms()#记录按键用时
oled.fill(0)
oled.show()#清空oled
g_on()#绿灯亮,单次测试结束,查看结果
ws2812b.off(cs_led)#灯灭
break
react_time = end_time - start_time#计算反应时间
oled.text("TIME:", 12, 10)
oled.text('{:3.3f}s'.format(react_time/1000), 12, 20)
oled.show()
oled.text("press k1", 12, 30)
oled.text("to restart", 12, 40)
oled.show()#显示结果与操作提示
print("Reaction time is "+ str(react_time/1000)+ "s")
time.sleep(0.3)
七、遇到的问题
oled显示屏如果不清空,输出内容会重叠在一起。通过自己的摸索,找到了使用oled.fill(0)的方法来刷新清空显示屏,使显示屏输出能够按照想法进行。
八、未来的建议
还可以拓展更多的功能,同时优化显示。功能上,可以由单一的“亮灯按键测量反应”的功能扩展出许多要求更严格的功能。例如:利用RGB灯色彩的多样性,RGB亮起颜色为红色时,按下k1,亮起颜色为绿色时,按下k2,否则视作未反应,直到正确按键被按下;或者利用RGB灯点亮的随机性,点亮灯号为奇数号灯时,应按下k1,偶数号灯亮起时,应按下k2。人类反应时间的测量是一件非常复杂而多样的事情,因此本项目,反应测试器还具有非常广大的功能扩展改造空间。