1 项目需求
使用树莓派pico制作一个反应时间的检测,随机点亮板上的一个LED,按下板上的一个按键,在显示屏上显示出从灯亮到按键之间的时间,这是心理学上的一个重要实验。
并且可以控制12个rgb彩灯和蜂鸣器一起实现不同的显示声光效果。
2 使用部分硬件介绍
首先是他的主控模块树莓派pico的基础模块由rp2040芯片控制,其次看到的是其外接的reb彩灯,reb彩灯通过不同的编码可以显示出上万种颜色,接下来是外接oled显示屏,可以显示一些字符,还有蜂鸣器模块,通过输出不同的pwm信号使蜂鸣器产生不同的旋律,从而达到播放音乐的目的本项目主要用到这么多模块。
3 完成的功能及达到的性能
3.1 通过软件产生随机数,程序启动以后在随机数控制的时间下点亮板上的LED,被测试者按下按键以后,处理器计算从点亮灯到接收到按键之间的时间差,并将时间差通过USB显示在PC上,也可以将OLED用起来,在OLED上显示时间信息。
3.2 板上有12个排列成圆圈的彩色LED灯WS2812B,通过编程实现各种炫酷的展示效果,并且搭配上蜂鸣器,做出了声光具备的作品。
4 实现思路
检测反应时间的主要实现思路是通过软件产生随机数,程序启动以后在随机数控制的时间下点亮板上的第一个reb灯,被测试者按下按键以后,处理器计算从点亮灯到接收到按键之间的时间差,并将时间差通过USB显示在PC和oled上,在这个过程中按键采用的是中断的功能,当按下按键之后代码去执行计算从亮灯到按下按键的时间,采用减法运算代码更简单。
炫彩灯光秀主要的实现思路是先通过网上资源查找rgb彩灯显示不同颜色的编码,对应编码显示出彩灯,挑选自己喜欢的颜色先亮四个一次循环可以得到炫酷的不同颜色的流水彩灯,在挑选自己喜欢的颜色的彩灯从1-12做循环减小延时时间观察到另一种炫酷的彩灯。在彩灯结束之后回亮起白色的灯光播放两只老虎,这主要是通过改变输出的pwm从而使蜂鸣器发出不同的声音最后把两只老虎的音乐旋律转换为对应的pwm即可。
5 实现过程
5.1 实现过程流程图
5.2 对rgb彩灯进行编码为下面的彩灯显示提供不同颜色
def water_light():#2812b流水灯
t=0.1
for i in range(1,13):
ws2812b.on()
time.sleep(t)
ws2812b.on(,"#ff0000")#红色
time.sleep(t)
ws2812b.on(,"#00ff00")#绿色
time.sleep(t)
ws2812b.on(,"#ffff00")#黄色
time.sleep(t)
ws2812b.on(,"#E6E8FA")
time.sleep(t)
ws2812b.on(,"#9932CD")
time.sleep(t)
ws2812b.on(,"#D9D919")#
time.sleep(t)
ws2812b.on(,"#CD7F32")#金色
time.sleep(t)
ws2812b.on(,"#4169E1")#品蓝
time.sleep(t)
ws2812b.on(,"#DA70E6")#淡紫色
time.sleep(t)
ws2812b.on(,"#5E2612")#乌贼墨棕
time.sleep(t)
ws2812b.off(1)
显示不同颜色的四个灯一次循环
def google_home():
google_colors = ['#ff0000','#ffff00','#00ff00','#DA70E6']
cycles = 1 # number of times to cycle 360-degrees
for jj in range(int(cycles*len(pixel_array))):
for ii in range(len(pixel_array)):
if ii%int(math.ceil(len(pixel_array)/4))==0:
set_24bit((ii+jj)%12,google_colors[int(ii/len(pixel_array)*4)])
else:
set_24bit((ii+jj)%12,'#000000')
update_pix()
time.sleep(0.1)
def google_home1():
google_colors = ['#CD7F32','#4169E1','#DA70E6','#5E2612']
cycles = 1 # number of times to cycle 360-degrees
for jj in range(int(cycles*len(pixel_array))):
for ii in range(len(pixel_array)):
if ii%int(math.ceil(len(pixel_array)/4))==0:
set_24bit((ii+jj)%12,google_colors[int(ii/len(pixel_array)*4)])
else:
set_24bit((ii+jj)%12,'#000000')
update_pix() # update pixel colors
time.sleep(0.1) # wait between changes
亮一种颜色的灯从1-12循环
red_light()
time.sleep(0.5)
yellow_light()
time.sleep(0.5)
green_light()
time.sleep(0.5)
w5()
time.sleep(0.5)
5.3 播放两只老虎
pwm=PWM(Pin(19))
pwm.duty_u16(360)
pwm.freq(1000)
a=[525,525,589,589,661,661,525,525,525,525,589,589,661,661,525,525,661,661,700,700,786,786,786,786,661,661,700,700,786,786,786,786,786,882,786,700,661,661,525,525,786,882,786,700,661,661,525,525,589,589,393,393,525,525,525,525,589,589,393,393,525,525,525,525]
for i in a:
pwm.freq(i)
time.sleep(0.2)
pwm.deinit()
5.4 检测反应时间,通过按下按键去执行中断中的代码,计算从亮灯开始到按下按键的时间,这里采用减法运算。
def k1_callback(pin):
global timer_start
timer_reaction = time.ticks_ms() - timer_start # ticks_diff
print_result("time = " + str(timer_reaction) + "ms")
k1 = button(pin_cfg.k1, k1_callback, trigger=Pin.IRQ_FALLING)
5.5 运行主函数达到预期实验效果
while True:
google_home()
oldeshow()
google_home1()
red_light()
time.sleep(0.5)
yellow_light()
time.sleep(0.5)
green_light()
time.sleep(0.5)
w5()
time.sleep(0.5)
lzlh()
ws2812b.off_all()
time.sleep(0.5)
ws2812b.on(1)
oled.fill(0)
time.sleep(random.uniform(3,50))
ws2812b.off(1)
timer_start = time.ticks_ms()
time.sleep(100)
6 遇到的主要难题
6.1 在检测反应时间时遇到的主要难题就是oled屏幕的数字显示,在第一次按下按键后在oled和pc端同时显示反应时间,但在多按下几次之后pc端显示正常,oled上的显示就会变得模糊,我一开始猜测可能是没有清屏造成的,但是加上了清屏语句之后依然是这样,查阅资料之后发现可能是屏幕的刷新率不够需要调整一下。
6.2 还遇到的一个问题就是中断问题,就是当两个按键都使用了中断之后涉及到中断优先的问题,不然从这个中断跳到另一个中断跳不出来,达不到想要的项目效果。
7 未来的计划和建议
在整个学习过程中我发现整个课程的讲解非常的条理清晰,让我学到了很多,在学习一个项目之前,要先有一个总的规划,把所需要的东西找齐放在一个文件夹中,方便日后查阅,减少多次找资料带来的时间浪费。在未来,还需要进一步的学习micropython这门编程语言,继续开发树莓派的功能,争取早日可以自己写树莓派的库。
希望未来硬禾学堂可以出更多的优秀好玩的项目,可以全方位的提升自己。