基于树莓派PICO制作反应测试器
本项目是实现一个反应测试器,测试从随机亮起一盏灯到按下按钮的时间差作为人的反应时间。
标签
嵌入式系统
MicroPython
树莓派PICO
2023寒假在家练
反应测试器
xxxx
更新2023-03-28
北京理工大学
468
  • 项目介绍

项目目的:本项目的目标是基于STEP Pico制作一个反应测试器,通过计算灯亮时间到按键时间之差实现对人的反应时间的测试。

基本要求:经过随机时间,随机点亮板上的一个LED,按下板上的一个按键后,在显示屏上显示出从灯亮到按键之间的时间。

拓展功能:实现自主控制进行多轮游戏,并增加最佳反应时间的记录。

 

  • 设计思路

通过软件产生随机数,程序启动以后在随机数控制的时间下点亮板上的LED,被测试者按下按键以后,处理器计算从点亮灯到接收到按键之间的时间差,并将时间差通过USB显示在PC上,也将OLED用起来,在OLED上显示时间信息。

 

  • 环境配置

1.thonny:

Thonny 由爱沙尼亚的 Tartu 大学开发,它采用了不同的方法,因为它的调试器是专为学习和教学编程而设计的。它易于上手,查看变量方便,页面简洁,基础功能齐全,简单易上手,非常适合初学者。

2.硬禾学堂树莓派pico平台:

硬禾学堂为“2023寒假一起练”制作了一个平台,此平台作为2023年寒假在家一起练的平台之一,提供了详细的项目介绍、板卡硬件介绍、开源代码以及配套的视频直播课程,以便于初学者快速掌握,网址为:https://www.eetree.cn/project/detail/584

3.micropython:

MicroPython [1]  是 Python 3 语言的精简实现 ,包括Python标准库的一小部分,经过优化可在微控制器和受限环境中运行。除了实现一系列核心Python库之外,MicroPython还包括用于访问低级硬件的“机器”等模块。

 

  • 流程图

Ft4az95qNC_YKER7UuHAfZ_oeFWE

  • 硬件介绍

本项目基于树莓派Pico的嵌入式系统学习平台,专为嵌入式系统学习而设计,其可以通过C/C++以及MicroPython编程来学习嵌入式系统的工作原理和应用。板卡为树莓派Pico扩展板和硬禾版本树莓派Pico核心模块 - STEP Pico

板卡硬件:

2个按键输入

4个单色LED

12个WS2812B RGB三色灯

1个姿态传感器

1个128*64 OLED显示屏

1个蜂鸣器

1个可调电位计(用于电压表)

1路音频信号输入(用于示波器)

8位R-2R电阻网络构成的DAC(用于DDS信号发生器)

FgTH28pLI80kAVQXu161Fx1wotU9

功能及管脚映射表:

Fine2TE6eh2jfN4GfBcV4LT0C1vS

 

 

  • 实现的功能及图片展示

1.运行程序,游戏开始。

 

2.按下K2按钮,开始一局的测试。OLED上将提示“Begin!”

FiL7mKlrhXH_9KhrvvydrIaAaUZZ

3.经过随机生成的时间Tn后,随机N号LED灯将亮起

FghQxLcDL_afSwfO0ApLtA8lD5FV

4.按下K1按钮,LED灯熄灭,此时自动计算灯亮起到按下K1按钮的时间差,并显示在OLED上。同时会记录下此次游戏中最佳时间(即最快反应时间)并一同显示在OLED上。

FtjDNvnf-x9UKWBD_lyKDxMZpqQL

  1. 可再次或多次按下K2按钮,继续再一局游戏。在程序结束前,将一直保存最佳时间。
  • 主要代码片段及说明
from machine import Pin, SPI

from ssd1306 import SSD1306_SPI

import framebuf

from board import pin_cfg




spi = SPI(1, 100000, mosi=Pin(pin_cfg.spi1_mosi), sck=Pin(pin_cfg.spi1_sck))

oled = SSD1306_SPI(128, 64, spi, Pin(pin_cfg.spi1_dc),Pin(pin_cfg.spi1_rstn), Pin(pin_cfg.spi1_cs))

通过SPI协议,导入ssd1306固件,在OLED屏上输出文字信息。

 

 

def k1_callback(pin):

    global timer_start

    global best_time

    timer_reaction = time.ticks_ms() - timer_start # ticks_diff

    print_result("Time:" + str(timer_reaction) + "ms")

    if timer_reaction < best_time :

        best_time = timer_reaction

    print_best_result("Best time:" + str(best_time) + "ms")

    ws2812b.off_all()

    oled.fill(0)

k1 = button(pin_cfg.k1, k1_callback, trigger=Pin.IRQ_FALLING)

在K1按钮及其回调函数中,先定义了两个全局变量timer_start和best_time分别用于存储灯亮开始时刻和此次游戏最佳反应时间。然后计算本局游戏反应时间,并比对最佳反应时间,最后将两个数据信息通过调用oled.text()和oled.show()函数显示在OLED灯上。语句oled.fill(0)用于OLED灯的清除屏幕。

 

 

def k2_callback(pin):

    global timer_start

    print_result("Begin!")

    time.sleep(random.uniform(3,5))

    ws2812b.on(random.randint(1,12))

    timer_start = time.ticks_ms()

    oled.fill(0)

k2 = button(pin_cfg.k2, k2_callback, trigger=Pin.IRQ_FALLING)

在K2按钮及其回调函数中,沿用了K1按钮中的全局变量timer_start,按下按钮后显示“Begin!”以提示玩家。然后随机生成大于等于3小于5的浮点数作为随机时间,生成1到12的随机整数(由于板子上共有12个LED灯,序号分别为1到12)作为随机亮起的LED灯,同时重置timer_start记录灯亮时刻。

 

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

1.常规的循环结构加sleep函数只能实现被动开始游戏,即只能在sleep函数持续时间结束后才开始随机亮灯。

解决办法:引入K2按钮及其回调函数,将循环开始游戏改为按下K2进行游戏,实现了自主控制多轮游戏。

2.由于多次进行游戏,频繁且交替地输出了各种提示信息,导致OLED灯显示重叠,影响测试结果的显示。

解决办法:在每次输出完交互信息后,执行oled.fill(0)语句,将OLED灯的文本信息清除(信息清除并不等价于清屏,屏幕上仍然显示原先的信息)。

3.由于引入了两个按钮及其回调函数(即K1、K2按钮),并且K2中产生随机数进行亮灯,K1中需要将其熄灭,无法对K2中的随机数进行传递。

解决办法:不论点亮了哪个编号的LED灯,在K1中直接熄灭全部的灯,即把全部LED灯的color属性设置为"#000000"。

 

  • 未来的计划或建议

1.继续学习micropython和STEP Pico的硬件结构和信息,深入研究其各个功能。

2.考虑到单次测量反应时间的结果具有较大不确定度,因此计划尝试在一局测试中进行连续多次亮灯-按键的循环测试,计算多次结果求取平均值作为本次反应时间的结果,并计算方差以评估测试者的反应稳定性。

3.增强趣味性和挑战性,计划尝试双人竞争的反应时间测试,如设置一局测试共十轮,每轮将随机亮起1个LED灯或2个LED灯,测试者A只能在亮起1个LED灯后按键,测试者B则为2个LED,最后统计各自的结果。

 

 

附件下载
代码.zip
团队介绍
徐恒 北京理工大学
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号