基于树莓派RP2040设计lcd与电脑的鼠标
本设计采用树莓派Pico核心芯片RP204 为处理核心,以硬禾学堂的游戏机上面的四向摇杆和3个轻触按键用做输入控制,实现了lcd与电脑上鼠标的控制。利用四向摇杆实现鼠标的移动,游戏机上面的按键则对应鼠标的左右键和鼠标中键
标签
树莓派
嵌入式系统
RP2040
2022寒假在家练
doctor雷
更新2022-03-02
湖北理工学院
603

项目介绍:基于树莓派Pico的嵌入式系统学习平台,利用板上的四向摇杆和按键设计一款“鼠标”,在240*240的LCD屏幕内可以通过该鼠标进行电脑鼠标移动速度的变化,电脑鼠标速度分为三种模式:最慢,慢,快。最后通过USB端口可以控制PC屏幕上的光标移动和点击操作,行使电脑鼠标的功能

设计思路:大体思路如下。通过板子上的ADC获取四向遥感的数据和按键状态,最后交给芯片rp2040进行处理。通过spi协议驱动st7789屏幕显示鼠标以及参数,最后通过USB数据线传递指令使鼠标移动。

FjF__9KNoUFYV2giaC0RIvs2NePd

软件思路:程序初始化,然后进入主循环,在主循环下面进行模式判断,模式分别为鼠标速度的快慢,最后结束。

 

FkenGrVZ00XB4PlukFnWM5gK050h

游戏机的硬件信息:

树莓派Pico核心芯片RP2040,双核Arm Cortex M0+内核,可以运行到133MHz,

同时支持MicroPython编程。同时拥有240*240分辨率的彩色IPS,LCD,SPI接口,

控制器为ST7789。四向摇杆和3个轻触按键用做输入控制。另外板上外扩2MB Flash,

可以预刷MicroPython的UF2固件,USB Type C连接器用于供电、程序下载,以及数据的传输。

代码实现了电脑鼠标移动速度的选择,控制电脑鼠标移动速度分三个挡位,效果图如下

Fgi24t_WR4vlRCabQoAJ9R0ihh66

程序main代码如下:其作用我将用注释

#引用一些必须的库
from machine import Pin, SPI, ADC
import utime
from hid import Mouse#鼠标库
import st7789c#st7789屏幕驱动库
from board import game_kit#游戏机板子按键
from fonts import vga2_8x8 as font1
from fonts import vga1_16x32 as font2#以上两个为字库
import framebuf

xAxis = ADC(Pin(28))
yAxis = ADC(Pin(29))
buttonB = Pin(5,Pin.IN, Pin.PULL_UP) #B
buttonA = Pin(6,Pin.IN, Pin.PULL_UP) #A
buttonStart = Pin(7,Pin.IN, Pin.PULL_UP) 
buttonSelect = Pin(8,Pin.IN, Pin.PULL_UP) 
mouse=Mouse()
spi = SPI(0, baudrate=31250000, polarity=1, phase=1,
                  sck=Pin(game_kit.lcd_sck, Pin.OUT),
                  mosi=Pin(game_kit.lcd_sda, Pin.OUT))
tft = st7789c.ST7789(
            spi,
            240,
            240,
            reset=Pin(game_kit.lcd_rst, Pin.OUT),
            dc=Pin(game_kit.lcd_dc, Pin.OUT),
            rotation=0)
tft.init()
def draw_shubiao(x,y,T):#画鼠标
    tft.hline(0,160,230,st7789c.WHITE)
    tft.hline(0,165,230,st7789c.WHITE)
    tft.text(font1, "Sensitivity:", 10, 130)
    tft.text(font2, "-", 130, 120)
    tft.text(font2, "+", 210, 120)
    tft.text(font1, "Press A to confirm", 10, 100)
    tft.text(font2, "LCD_PC control", 10, 50)
    f_image = open("/logo2.bin", 'rb')
    for column in range(y,y+40):
                    buf=f_image.read(80)
                    tft.blit_buffer(buf, x,column, 40, 1)
class Bat:
    def __init__(self, x):
        self.x = x
class Bat1:
    def __init__(self, y):
        self.y = y
bat = Bat(0)
bat1 = Bat1(0)
#main loop
while True:
    a=5
    T=0
    in_min,in_max,out_min,out_max = (0, 65000, -a, a)#-2 2 10 -10
    filter_joystick_deadzone = lambda x: int((x - in_min) * \
    (out_max - out_min) / (in_max - in_min) + out_min) if abs(x - 32768) > 500 else 0
    xValue = xAxis.read_u16()
    yValue = yAxis.read_u16()
    A = buttonA.value()
    B = buttonB.value()
    buttonValueSelect = buttonSelect.value()
  #获取的摇杆电压数据进入函数处理得到鼠标移动的数字
    x_offset = filter_joystick_deadzone(xValue)
    y_offset = filter_joystick_deadzone(yValue)
#     mouse.move(y_offset, x_offset,0 ,0)#鼠标移动函数
#lcd mouse through
    if y_offset==a :
        tft.fill(st7789c.BLACK)
        bat.x = bat.x +1
        if bat.x>200:
            bat.x=10        
    if y_offset==-(a-1):
        tft.fill(st7789c.BLACK)
        bat.x = bat.x -1
        if bat.x<0:
            bat.x=200
    if x_offset==(a-1) :
        bat1.y = bat1.y +1
        if bat1.y>240:
            bat1.y=1
    if x_offset==-(a-1) :
        tft.fill(st7789c.BLACK)
        bat1.y = bat1.y -1
        if bat1.y<0:
            bat1.y=230
#progress bar
    if bat.x<80 and bat1.y>130 and bat1.y<170:
        tft.text(font1, "Slowest", 150, 130)
        tft.fill_rect(80, 160, 150, 5, st7789c.WHITE)
        tft.fill_rect(2, 160, 80, 5, st7789c.RED)
        T=1
    elif bat.x>80 and bat.x<110 and bat1.y>130 and bat1.y<170:
        tft.text(font1, "Slow", 150, 130)
        tft.fill_rect(2, 160, 80, 5, st7789c.WHITE)
        tft.fill_rect(80, 160, 80, 5, st7789c.RED)
        tft.fill_rect(160, 160, 70, 5, st7789c.WHITE)
        T=2
    elif bat.x>110 and bat.x<230 and bat1.y>130 and bat1.y<170:
        tft.text(font1, "Fast", 150, 130)
        tft.fill_rect(160, 160, 70, 5, st7789c.RED)
        tft.fill_rect(20, 160, 160, 5, st7789c.WHITE)
        T=3
#   debug  print(bat.x,bat1.y)
    draw_shubiao(bat.x,bat1.y,T)    
    utime.sleep(0.01)
    if A==0 and T==1:
        while True:
            a=2
            tft.text(font1, "Slowest", 150, 130)
            in_min,in_max,out_min,out_max = (0, 65000, -a, a)#-2 2 10 -10
            filter_joystick_deadzone = lambda x: int((x - in_min) * \
            (out_max - out_min) / (in_max - in_min) + out_min) if abs(x - 32768) > 500 else 0
            xValue = xAxis.read_u16()
            yValue = yAxis.read_u16()
            A = buttonA.value()
            B = buttonB.value()
            buttonValueSelect = buttonSelect.value()
            x_offset = filter_joystick_deadzone(xValue)  #获取的摇杆电压数据进入函数处理得到鼠标移动的数字
            y_offset = filter_joystick_deadzone(yValue)
        #lcd mouse through
            if y_offset==a :
                tft.fill(st7789c.BLACK)
                bat.x = bat.x +1
                if bat.x>200:
                    bat.x=10        
            if y_offset==-(a-1):
                tft.fill(st7789c.BLACK)
                bat.x = bat.x -1
                if bat.x<0:
                    bat.x=200
            if x_offset==(a-1) :
                bat1.y = bat1.y +1
                if bat1.y>240:
                    bat1.y=1
            if x_offset==-(a-1) :
                tft.fill(st7789c.BLACK)
                bat1.y = bat1.y -1
                if bat1.y<0:
                    bat1.y=230
        #progress bar
            if bat.x<80 and bat1.y>130 and bat1.y<170:
                tft.text(font1, "Slowest", 150, 130)
                tft.fill_rect(80, 160, 150, 5, st7789c.WHITE)
                tft.fill_rect(2, 160, 80, 5, st7789c.RED)
                T=1
            elif bat.x>80 and bat.x<110 and bat1.y>130 and bat1.y<170:
                tft.text(font1, "Slow", 150, 130)
                tft.fill_rect(2, 160, 80, 5, st7789c.WHITE)
                tft.fill_rect(80, 160, 80, 5, st7789c.RED)
                tft.fill_rect(160, 160, 70, 5, st7789c.WHITE)
                T=2
            elif bat.x>110 and bat.x<230 and bat1.y>130 and bat1.y<170:
                tft.text(font1, "Fast", 150, 130)
                tft.fill_rect(160, 160, 70, 5, st7789c.RED)
                tft.fill_rect(20, 160, 160, 5, st7789c.WHITE)
                T=3
        #   debug  print(bat.x,bat1.y)
            mouse.move(y_offset, x_offset,0 ,0)#鼠标移动函数
            draw_shubiao(bat.x,bat1.y,T)    
            utime.sleep(0.01)
            if A==0: 
              mouse.click(Mouse.BUTTON_RIGHT)#鼠标右键
              tft.text(font2, "BUTTON_RIGHT ", 10, 10)         
            if B==0:
                     mouse.press(Mouse.BUTTON_LEFT)
                     tft.text(font2, "BUTTON_LEFT  ", 10, 10)
            else:
                     mouse.release(Mouse.BUTTON_LEFT)
            buttonValueSelect = buttonSelect.value()
            if buttonValueSelect==0:
                 tft.text(font2, "BUTTON_MIDDLE", 10, 10)
                 mouse.move(0, 0,-x_offset,y_offset)
            if A==0 and T!=1:
                break
    if A==0 and T==3:
        while True:
            a=50
#             tft.text(font1, "BUTTON_RIGHT ", 10, 10)
            tft.text(font1, "Fast", 150, 130)
            in_min,in_max,out_min,out_max = (0, 65000, -a, a)#-2 2 10 -10
            filter_joystick_deadzone = lambda x: int((x - in_min) * \
            (out_max - out_min) / (in_max - in_min) + out_min) if abs(x - 32768) > 500 else 0
            xValue = xAxis.read_u16()
            yValue = yAxis.read_u16()
            A = buttonA.value()
            B = buttonB.value()
            buttonValueSelect = buttonSelect.value()
            x_offset = filter_joystick_deadzone(xValue)  #获取的摇杆电压数据进入函数处理得到鼠标移动的数字
            y_offset = filter_joystick_deadzone(yValue)
        #lcd mouse through
            if y_offset==a :
                tft.fill(st7789c.BLACK)
                bat.x = bat.x +1
                if bat.x>200:
                    bat.x=10        
            if y_offset==-(a-1):
                tft.fill(st7789c.BLACK)
                bat.x = bat.x -1
                if bat.x<0:
                    bat.x=200
            if x_offset==(a-1) :
                bat1.y = bat1.y +1
                if bat1.y>240:
                    bat1.y=1
            if x_offset==-(a-1) :
                tft.fill(st7789c.BLACK)
                bat1.y = bat1.y -1
                if bat1.y<0:
                    bat1.y=230
        #progress bar
            if bat.x<80 and bat1.y>130 and bat1.y<170:
                tft.text(font1, "Slowest", 150, 130)
                tft.fill_rect(80, 160, 150, 5, st7789c.WHITE)
                tft.fill_rect(2, 160, 80, 5, st7789c.RED)
                T=1
            elif bat.x>80 and bat.x<110 and bat1.y>130 and bat1.y<170:
                tft.text(font1, "Slow", 150, 130)
                tft.fill_rect(2, 160, 80, 5, st7789c.WHITE)
                tft.fill_rect(80, 160, 80, 5, st7789c.RED)
                tft.fill_rect(160, 160, 70, 5, st7789c.WHITE)
                T=2
            elif bat.x>110 and bat.x<230 and bat1.y>130 and bat1.y<170:
                tft.text(font1, "Fast", 150, 130)
                tft.fill_rect(160, 160, 70, 5, st7789c.RED)
                tft.fill_rect(20, 160, 160, 5, st7789c.WHITE)
                T=3
        #   debug  print(bat.x,bat1.y)
            print(y_offset, x_offset,bat.x,bat1.y)
            if x_offset==-3 or x_offset==-2 or x_offset==-4 or x_offset==-1:
                x_offset=0
            mouse.move(y_offset, x_offset,0 ,0)#鼠标移动函数
#             tft.text(font1, "X= "+str(y_offset), 10, 210)
#             tft.text(font1, "Y= "+str(x_offset), 10, 220)
            draw_shubiao(bat.x,bat1.y,T)    
            utime.sleep(0.01)
            if A==0: 
              mouse.click(Mouse.BUTTON_RIGHT)#鼠标右键
              tft.text(font2, "BUTTON_RIGHT ", 10, 10)         
            if B==0:
                     mouse.press(Mouse.BUTTON_LEFT)
                     tft.text(font2, "BUTTON_LEFT  ", 10, 10)
            else:
                     mouse.release(Mouse.BUTTON_LEFT)
            buttonValueSelect = buttonSelect.value()
            if buttonValueSelect==0:
                 tft.text(font2, "BUTTON_MIDDLE", 10, 10)
                 mouse.move(0, 0,-x_offset,y_offset)
            if A==0 and T!=3:
                break
    if A==0 and T==2:
        while True:
            a=10
            tft.text(font1, "Slow", 150, 130)
            in_min,in_max,out_min,out_max = (0, 65000, -a, a)#-2 2 10 -10
            filter_joystick_deadzone = lambda x: int((x - in_min) * \
            (out_max - out_min) / (in_max - in_min) + out_min) if abs(x - 32768) > 500 else 0
            xValue = xAxis.read_u16()
            yValue = yAxis.read_u16()
            A = buttonA.value()
            B = buttonB.value()
            buttonValueSelect = buttonSelect.value()
            x_offset = filter_joystick_deadzone(xValue)  #获取的摇杆电压数据进入函数处理得到鼠标移动的数字
            y_offset = filter_joystick_deadzone(yValue)
        #lcd mouse through
            if y_offset==a :
                tft.fill(st7789c.BLACK)
                bat.x = bat.x +1
                if bat.x>200:
                    bat.x=10        
            if y_offset==-(a-1):
                tft.fill(st7789c.BLACK)
                bat.x = bat.x -1
                if bat.x<0:
                    bat.x=200
            if x_offset==(a-1) :
                bat1.y = bat1.y +1
                if bat1.y>240:
                    bat1.y=1
            if x_offset==-(a-1) :
                tft.fill(st7789c.BLACK)
                bat1.y = bat1.y -1
                if bat1.y<0:
                    bat1.y=230
        #progress bar
            if bat.x<80 and bat1.y>130 and bat1.y<170:
                tft.text(font1, "Slowest", 150, 130)
                tft.fill_rect(80, 160, 150, 5, st7789c.WHITE)
                tft.fill_rect(2, 160, 80, 5, st7789c.RED)
                T=1
            elif bat.x>80 and bat.x<110 and bat1.y>130 and bat1.y<170:
                tft.text(font1, "Slow", 150, 130)
                tft.fill_rect(2, 160, 80, 5, st7789c.WHITE)
                tft.fill_rect(80, 160, 80, 5, st7789c.RED)
                tft.fill_rect(160, 160, 70, 5, st7789c.WHITE)
                T=2
            elif bat.x>110 and bat.x<230 and bat1.y>130 and bat1.y<170:
                tft.text(font1, "Fast", 150, 130)
                tft.fill_rect(160, 160, 70, 5, st7789c.RED)
                tft.fill_rect(20, 160, 160, 5, st7789c.WHITE)
                T=3
        #   debug  print(bat.x,bat1.y)
            print(y_offset, x_offset,bat.x,bat1.y)
            mouse.move(y_offset, x_offset,0 ,0)#鼠标移动函数
            draw_shubiao(bat.x,bat1.y,T)    
            utime.sleep(0.01)
            if A==0: 
              mouse.click(Mouse.BUTTON_RIGHT)#鼠标右键
              tft.text(font2, "BUTTON_RIGHT ", 10, 10)         
            if B==0:
                     mouse.press(Mouse.BUTTON_LEFT)
                     tft.text(font2, "BUTTON_LEFT  ", 10, 10)
            else:
                     mouse.release(Mouse.BUTTON_LEFT)
            buttonValueSelect = buttonSelect.value()
            if buttonValueSelect==0:
                 tft.text(font2, "BUTTON_MIDDLE", 10, 10)
                 mouse.move(0, 0,-x_offset,y_offset)
            if A==0 and T!=2:
                break


未来希望可以将鼠标更多参数添加,如在LCD屏幕上实现鼠标可以点击效果。同时拓展一个屏幕实现鼠标移动。

在项目开始之初,我遇到最大的难题在于树莓派rp2040的学习,以及micro python语言的学习,这些都是自己不熟悉的,好在只要自己坚持与努力,这些一边学一边做,最后成功完成该项目,在项目之中,听取老师和群友意见,网上查阅资料,后上机验证,最后移植到自己的程序。未来打算将屏幕刷新率做一些改善。同时扩展其他的新功能。如菜单切换,返回上一级等等。

附件下载
2022硬禾项目.7z
有刷入的固件
团队介绍
一个人的团队
团队成员
doctor雷
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号