基于树莓派Pico制作反应测试器
基于树莓派Pico实现随机点亮板上的一个LED,按下板上的一个按键,在显示屏上显示出从灯亮到按键之间的时间,这是心理学上的一个重要实验
标签
嵌入式系统
测试
显示
2023寒假一起练
不合时宜
更新2023-03-29
北京理工大学
437

1 项目需求和硬件介绍

1.1 项目需求——制作一个反应测试器

具体要求:随机点亮板上的一个LED,按下板上的一个按键,在显示屏上显示出从灯亮到按键之间的时间,这是心理学上的一个重要实验

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

1.2 硬件介绍

Step Pico是一款低成本,高性能的微控制器开发板,具有灵活数字接口。基于树莓派Pico的嵌入式系统学习平台,专为嵌入式系统学习而设计,其可以通过C/C++以及MicroPython编程来学习嵌入式系统的工作原理和应用。

板卡硬件:

2个按键输入

4个单色LED

12个WS2812B RGB三色灯

1个姿态传感器

1个128*64 OLED显示屏

1个蜂鸣器

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

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

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

2 完成的功能以及达到的性能

2.1 游戏开始的预告

9k=

每局反应游戏开始前,灯会亮三秒,然后熄灭三秒,之后游戏开始,给玩家反应时间。

2.2 游戏开始,随机的led灯亮起

Z9k=

四个led灯随机亮起3到5秒,然后熄灭。玩家需要按下k1键,然后oled屏上就会出现从灯灭到玩家按下k1键中间的时间,即为反应时间。每局游戏相隔10秒,十秒之后会开始新的一局。

3 实现思路

使用Micropython的machine模块配置了板上的LED和按键引脚。然后使用GPIO输出高电平来点亮LED,并使用utime模块等待一段随机的时间。

随后,使用一个while循环来等待按键被按下。在while循环中,我们不断地读取按键的状态,直到按键被按下为止。

一旦按键被按下,就计算出灯亮到按键按下的时间差,然后在显示屏上显示这个时间。

4 实现过程

Fin6LTrH0uVzKx3a7T8gPi1qi4Ud

4.1 配置led和按键引脚

配置按键引脚,定义位置button,调用位置React_Game

class button:

def __init__(self, pin, callback=None, trigger=Pin.IRQ_RISING, min_ago=200):

#print("button init")

self.callback = callback




self.min_ago = min_ago

self._next_call = time.ticks_add(time.ticks_ms(), self.min_ago)

self.pin = Pin(pin, Pin.IN, Pin.PULL_UP)

self.pin.irq(trigger=trigger, handler=self.debounce_handler)

self._is_pressed = False

def call_callback(self, pin):

#print("call_callback")

self._is_pressed = True

if self.callback is not None:

self.callback(pin)

def debounce_handler(self, pin):

#print("debounce")

if time.ticks_diff(time.ticks_ms(), self._next_call) > 0:

self._next_call = time.ticks_add(time.ticks_ms(), self.min_ago)

self.call_callback(pin)

def value(self):

p = self._is_pressed

self._is_pressed = False

return p

k1 = button(pin_cfg.k1)

配置灯,定义位置ws2812b,调用位置React_Game

LED_COUNT = 12 # number of LEDs in ring light

PIN_NUM = 18 # pin connected to ring light

brightness = 1.0 # 0.1 = darker, 1.0 = brightest

@rp2.asm_pio(sideset_init=rp2.PIO.OUT_LOW, out_shiftdir=rp2.PIO.SHIFT_LEFT,

autopull=True, pull_thresh=24) # PIO configuration

def ws2812():

T1 = 2

T2 = 5

T3 = 3

wrap_target()

label("bitloop")

out(x, 1) .side(0) [T3 - 1]

jmp(not_x, "do_zero") .side(1) [T1 - 1]

jmp("bitloop") .side(1) [T2 - 1]

label("do_zero")

nop() .side(0) [T2 - 1]

wrap()

配置old屏幕,定义位置oled,调用位置React_Game

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))

4.2 定义中断函数

定义中断函数,定义位置React_Game,调用位置React_Game

def k1_callback(pin):

global timer_start

timer_reaction=time.ticks_ms() - timer_start

print_result(str(timer_reaction)+" ms")

当按下k1按键后,启动中断程序,将反应时间打印在oled屏幕上,若重复按下k1按键,之前打印的会被清除掉,然后打印新的时间上去。每局游戏内重复按下k1按键只会显示该局内的时间。

下面是打印在oled上的函数print_result

def print_result(msg):

oled.fill(0)

oled.text("Reaction Time: ",0,20)

print(msg)

oled.text(msg,0,40)

oled.show()

4.3 主程序

While大循环,每局游戏开始前所有灯亮三秒,然后熄灭三秒,以提示玩家做好准备。然后在四个led灯中随机选取一个亮起,亮起时间为随机的3到5秒。每局游戏间隔10秒

while True:

ws2812b.on_all()

time.sleep(3)

ws2812b.off_all()

time.sleep(3)

led_On=random.choice(ledToChoose)

led_On.on()

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

led_On.off()

timer_start=time.ticks_ms()

time.sleep(10)

5 遇到的主要难题

最开始写的代码中,使用了一个while循环来等待按键被按下,这种方式被称为轮询方式。轮询方式的缺点是需要不断地查询按键的状态,因此会占用处理器的时间,可能导致其他任务的延迟。另外,如果按键被按下的时间非常短,可能会导致轮询方式无法及时检测到按键的状态。

后来使用中断可以避免这些问题,因为中断可以在按键被按下时立即执行相应的代码,而不需要等待查询按键状态。这样可以节省处理器的时间,并且可以及时响应按键事件。在Micropython中,可以使用machine模块的Pin类来配置引脚中断,实现按键的中断处理。

中断优先级问题:如果同时存在多个中断,可能会出现中断优先级的问题。在Micropython中,中断处理函数会在中断触发时立即执行,并且会屏蔽其他中断,直到中断处理函数执行完毕。如果存在多个中断,需要根据不同的中断优先级,适当地配置中断触发方式和中断处理函数,以避免中断冲突和竞争。

OLED屏幕驱动问题:如果OLED屏幕的驱动没有正确配置,可能会出现OLED屏幕无法正常显示的问题。在使用OLED屏幕时,需要确保正确配置OLED屏幕的驱动和初始化参数。

GPIO引脚使用问题:如果GPIO引脚的使用没有正确配置,可能会出现引脚无法输出或读取的问题。在使用GPIO引脚时,需要确保正确配置引脚的输入输出模式、上下拉电阻和引脚的电压和电流等参数。

6 未来的计划建议

增加更多的通信接口:除了GPIO引脚外,树莓派Pico扩展版还可以增加更多的通信接口,比如Ethernet、WiFi、Bluetooth、LoRa等。这样可以使树莓派Pico扩展版更加通用,可以用于更多的应用场景。

增加更多的存储空间:树莓派Pico扩展版可以增加更多的存储空间,比如Flash存储、SD卡接口等。这样可以存储更多的程序和数据,使树莓派Pico扩展版更加强大和实用。

增加更多的显示和输入接口:树莓派Pico扩展版可以增加更多的显示和输入接口,比如LCD显示屏、触摸屏、键盘等。这样可以使树莓派Pico扩展版更加易于使用和交互。

增加更多的扩展板和模块:树莓派Pico扩展版可以增加更多的扩展板和模块,比如机器人控制板、音频处理板、视频处理板等。这样可以使树莓派Pico扩展版更加多样化和实用。

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