基于step Pico 制作的反应测试器
本次主要基于pico实现项目1 反应测试器;实现过程是按k2 进行运行,熄灭所有灯,等随机灯亮起,开始计时,直到用户按K2 显示相应的反应时间
标签
PICO
RP2040
反应测试器
2023年寒假在家练
xinshuwei
更新2023-03-29
267
  • 项目描述(项目介绍、设计思路、框图和软件流程图)

         此次基于树莓派Pico的嵌入式系统学习平台实现项目1制作一个反应测试器.整体硬件框架如下:

Fq8smF921uug7ESZen_MH2bSpA2i

      两个按键用于开始结束/响应 ,OLED 用于显示 ,W2812 用于触发响应测试

      整体思路如下:

         1.点击KEY1 触发状态机开始,OLED 进行相应的提示

          2.软件开始随机定时,触发随机的w2812 进行点亮,同时开始计时

          3.等待用户点击Key2 ,点击后,将计算的反应时间显示到屏幕上

FvaZyKbYYzv4zIJHfzZPGkPuaZfe

  • 简单的硬件介绍Fm5kwfAqCrr2s4f73_SbbYdQwrFH

            此次核心板采用树莓派pico rp2040芯片控制器, 双核m0 最高运行133M。学习资源比较丰富,支持C/C++ 开发 支持micopython 开发 支持arduino 开发等多种方式,创客们玩的比较多,片上资源也比较丰富,SPI I2C PWM GPIO PIO 等一应俱全。

           搭配硬核提供的扩展板,可以学习ADC 采集 OLED 显示 W2812控制 按键 麦克风采集 PWM 蜂鸣器驱动等功能,非常适合大家进行学习 探讨。

  • 实现的功能及图片展示此次主要基于硬核提供的micropython 进行功能开发,已完成基本的oled 显示,按键触发、w2812驱动,随机数产生等功能,实现项目1 就是依据前面定的状态逻辑图进行功能组合,整体实现状态如下图

     FoRdXW71GRBkyu4y4Z7eMs6qzcjY

  • 主要代码片段及说明按键驱动   主要进行管脚指定,设定上升沿触发,200ms 进行延迟消抖
import time
from board import pin_cfg
from machine import Pin

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)
k2 = button(pin_cfg.k2)

oled 显示   基于ssd1306 实现屏幕显示驱动,指定spi 管脚,SSD1306寄存器配置等。

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))
oled.rotate(1)

由于需要输入中文,自己实现了中英文混输的方法,大概步骤如下:

1.使用pctolcd2000提取字模数据,设置格式如下:

FtSX4liHLh2j2JURrkUn5vOJgq4f

提取到的数组如下:

fonts= {
字模型:[0x00,0x00,0x00,0x08,0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x3E,0x00,0x00],#10
 
字模型:[0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x02,0x04,0x08,0x10,0x20,0x42,0x7E,0x00,0x00],#21
 
字模型:[0x00,0x00,0x00,0x3C,0x42,0x42,0x02,0x04,0x18,0x04,0x02,0x42,0x42,0x3C,0x00,0x00],#32
 
字模型:[0x00,0x00,0x00,0x04,0x0C,0x0C,0x14,0x24,0x24,0x44,0x7F,0x04,0x04,0x1F,0x00,0x00],#43
 
字模型:[0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x78,0x44,0x02,0x02,0x42,0x44,0x38,0x00,0x00],#54
 
字模型:[0x00,0x00,0x00,0x18,0x24,0x40,0x40,0x5C,0x62,0x42,0x42,0x42,0x22,0x1C,0x00,0x00],#65
 
字模型:[0x00,0x00,0x00,0x7E,0x42,0x04,0x04,0x08,0x08,0x10,0x10,0x10,0x10,0x10,0x00,0x00],#76
 
字模型:[0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x24,0x18,0x24,0x42,0x42,0x42,0x3C,0x00,0x00],#87
 
字模型:[0x00,0x00,0x00,0x38,0x44,0x42,0x42,0x42,0x46,0x3A,0x02,0x02,0x24,0x18,0x00,0x00],#98
 
字模型:[0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18,0x00,0x00],#09
 
}

编写了一个批量替换字典索引的python 脚本,功能是将上面的txt中"字模型"批量替换成对应字的utf-8 编码,用于程序使用时索引。使用时只需更新in_file  idx_txt 即可

 
#输入文件
in_file = "1.txt"
txt_idx = "字模型"
idx_txt = "1234567890"
hex_data =[]
def txt2hex(ch_str):
    global in_file
    global txt_idx
    global hex_data
    for k in ch_str:
       code = 0x00   
       data_code = k.encode("utf-8")
       size = len(data_code)
       code |= data_code[0] << 16
       if size ==1:
           code = code
       elif size ==2:
           code |= data_code[1] << 8
       else:
           code |= data_code[1] << 8
           code |= data_code[2]
       #print(k+"  "+hex(code))
       hex_data.append(str(hex(code)))
    file = open (in_file,'r',encoding="utf-8")
    lines = file.readlines()
    file.close()
    file = open(in_file,'w',encoding="utf-8")
    idx =0
    for con in lines:
        #print(con)
        if txt_idx in con:
            con = con.replace(txt_idx,hex_data[idx])
            idx=idx +1
        file.write(con)
    file.close()
 
 
        
    
    
txt2hex(idx_txt)  

python 中实际调用接口函数

def str2lcd(self,ch_str,xx,yy):
        for k in ch_str:
            if k in ("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijlkmnopqrstuvwxyz,.!(): "):
                #8*16 字符模型
                code =0x00
                data_code = k.encode("utf-8")
                #print("bytedata size ",len(data_code))
                byte_data = fonts[data_code[0]<<16]
                for y in range(0,16):
                    left8 = bin(byte_data[y]).replace('0b', '')
                    left8 = ('00000000'+left8)[-8:]    #如果不足8位,直接补齐8位,如从0010,补齐成00000010,代表汉字每一行左半部分8个像素点。0代表像素点不亮,1代表像素点亮
                    for x in range(0,8):
                        self.pixel(xx+x,yy+y,int(left8[x]))
                xx=xx+8
            else:
                code = 0x00  # 将中文转成16进制编码 
                data_code = k.encode("utf-8")
                code |= data_code[0] << 16 
                code |= data_code[1] << 8
                code |= data_code[2]
                byte_data = fonts[code]
                for y in range(0, 16):
                   left8 = bin(byte_data[y]).replace('0b', '')
                   left8 = ('00000000'+left8)[-8:]    #如果不足8位,直接补齐8位,如从0010,补齐成00000010,代表汉字每一行左半部分8个像素点。0代表像素点不亮,1代表像素点亮
                       
                   right8 = bin(byte_data[y+16]).replace('0b', '')
                   right8 = ('00000000'+right8)[-8:]    #代表汉字每一行右半部分8个像素点
                       
                   all16 = left8+right8   #拼成每一行16个像素点
                   
                   #print(all16)
                   for x in range(0, 16):      #开始循环检测,如果是1,则在这个位置点亮像素点
                       '''
                       if all16[x] == "1" :
                           self.pixel(xx+x,yy+y,255)
                       '''
                       self.pixel(xx+x,yy+y,int(all16[x]))
                xx=xx+16      #显示完一个汉字,显示下一个时,x位置向右移16像素 
  • 遇到的主要难题及解决方法

 最初只使用单键进行功能实现,后来发现逻辑有漏洞,后续增加开始结束按键,使整个逻辑判断更加严谨。

按键延迟不能调的太长,否则会与真是成绩有偏差

  • 未来的计划或建议后面多多举办这样的活动,让更多小伙伴们可以加入,一起学习交流
附件下载
main.py
团队介绍
苏州工程师一枚
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号