项目 - 制作一个反应测试器
1. 硬件介绍
STEP Pico是一款低成本,高性能的微控制器开发板,具有灵活数字接口(完全兼容Raspberry Pi Pico)。
硬件.上,采用Raspberry Pi官方自主研发的RP2040微控制器芯片,搭载了ARM Cortex M0+双核处理器,高达133MHz的运行频率,内置了264KB SRAM和2MB闪存,还板载有多达26个多功能的GPIO引脚。
软件上,可选择树莓派提供的C/C++SDK,或者使用MicroPython进行开发,树莓派Pico扩展版有以下硬件设备:
2个按键输入
4个单色LED
12个WS2812B RGB三色灯
1个姿态传感器
1个128*64 OLED显示屏
1个蜂鸣器
1个可调电位计(用于电压表)
1路音频信号输入(用于示波器)
8位R-2R电阻网络构成的DAC(用于DDS信号发生器)
在本次实验中我们仅需使用k1按键,12个ws2812b的RGB三色灯,以及OLED显示屏
2.项目需求
随机点亮板上的一个LED,按下板上的一个按键,在显示屏上显示出从灯亮到按键之间的时间,
3.实现思路
利用软件产生随机数用以控制随机点亮的LED,在提示准备后随机时间内亮起版上的LED,按下按键后,处理器计算从亮灯到接收按键之间的时间差,并将时间差显示在OLED屏上。
4.实现过程
首先拿到板子测试板子器件的功能正常使用
利用代码ws2812b.on与ws2812b.off测试12个LED灯是否正常工作
利用oled.text显示文字测试OLED显示屏是否正常显示
利用k1.value输出数字测试k1按键是否正确被按下
其次设计主题代码
使用中断服务程序控制k1按键,利用回调函数实现反应时间计算的执行,同时使用下降沿控制,使得按下按键后立刻得到反应时间,并在OLED显示屏上显示
编写主体循环代码,利用micro python中time.ticks函数作为时间的毫秒计数器,使用全局变量timer_start使得开始时间可以在中断服务中被使用从而计算反应时间。
5.主要代码与说明
在主体代码中利用随机数给cs_led赋值实现了在随机的时间内随机点亮一个ws2812b的LED灯,并且记录下灯亮的时间作为反应记录时间的开始。
定义了按键k1的回调函数,在按下k1后计算按键时间与亮灯时间的时间差,实现在OLED显示屏上显示出反应时间.
6.实验结果
7.实验中的创新点
在本次实验中,最为关键的技术在于使用到中断机制,因为要测试反应时间,因此k1按键的按下时间成为随机值。使用中断使得在主体循环时检测到k1按键按下时可以立即执行反应时间计算的步骤,从而能够得到精准的反应
8.未来的计划建议
该项目能够实现随机点亮LED灯测试按键反应时间的功能,并达到了预期指标。但在实验过程中仍遇到一些问题:
在一次实验过程中,如果多次按下k1按键,那么会记录下多次反应时间并全部显示重叠,改进思路是在循环中检测到一次k1按键后就不再接收k1。
才测试反应时间是可能会出现预判抢按,因此可以在测试出反应时间后对该反应时间进行测评,通过对多次测试反应的分布来判断其中个别反应的合理性。
该项目还可以有更多可以完成的功能:
可以将其改造成为一个具有随机颜色的反应灯,根据亮灯的不同颜色按下不同的按键,能够得到测试者的进一步反应水平,或者可以将其和音乐播放相结合,随机出现LED亮灯或放出声音来测试反应时间
9.实验心得
在本次参加树莓派举办的寒假一起练活动中,第一次接触了micropython编程,在课程中有老师详细的教学,让我了解了电子系统构成,初步掌握了与硬件直接相关的编程语言,也自己动手完成了一项有趣的项目,激发了我对微控制器开发板的兴趣
10.代码及解析
import ws2812b
from oled import oled
from button import button
from board import pin_cfg
import time
from machine import Pin
import random
def print_result(msg):
print(msg)
oled.text(msg,0,40)
oled.show() #定义一个输出函数以便将所需输出内容输出到oled显示屏上
timer_start = 0
def k1_callback(pin):
global timer_start #定义全局变量,方便在主循环内给予开始时间的值
timer_reaction = time.ticks_ms() - timer_start # 反应时间的计算式
oled.text("Reaction Time",0,25)
oled.show()
print_result(str(timer_reaction) + "ms")
oled.fill
k1 = button(pin_cfg.k1, k1_callback, trigger=Pin.IRQ_FALLING) #计数在按下按键的下降沿开始,数据准确
cs_led = 0
while True:
oled.fill(0)
oled.show()
cs_led = int(random.uniform(1,12)) #随机点亮1盏led灯
oled.text("Attention!",25,32)
oled.show()
time.sleep(random.uniform(3,4)) #等待随机时间后led灯亮起
oled.fill(0)
oled.show()
#ws2812b.on_all()
ws2812b.on(cs_led)
timer_start = time.ticks_ms() #灯亮后开始计时
time.sleep(2)
ws2812b.off_all()
time.sleep(random.uniform(5,6))
#timer_start = time.ticks_ms() #灯灭后开始计时
#time.sleep(random.uniform(5,8))