项目描述
项目介绍:
本项目采用的是RP2040 的gamekit开发板 制作一款类似于鼠标的应用demo。这个demo可以通过USB来控制鼠标的移动以及鼠标的左键和右键。同时可以通过遥感控制游戏机屏幕上面的鼠标按钮。
通过micropython来控制鼠标。
该项目具有以下功能:
-
能够通过遥感控制PC上面的鼠标
-
通过按键可以控制鼠标的左键和右键
-
可以通过屏幕上的鼠标来选择菜单
项目简单演示如下图所示:
设计思路
要完成这个项目的话,需要以下条件
-
rp2040 USB驱动要完成HID的通信,并且是免驱的,直接可以控制鼠标或者键盘的
-
RP2040需要采集到遥感的数据和按键的响应,并做出对应的动作
-
RP2040要能够在屏幕上显示图片和鼠标等
该项目整个硬件框图如图所示:
硬件介绍RP2040
-
RP2040是一款双核的两个M0+的MCU。 主频133MHz
-
片内RAM 264KB
-
外部采用QSPI总线连接芯片。
-
2 个 UART、2 个 SPI 控制器和 2 个 I2C 控制器
-
16 个 PWM 通道
芯片框图如图所示:
这款芯片具有USB 6块SRAM 以及PICO可编程单元。通过这张图可以看到两颗MCU Proc0 和 Proc1相互之间共用中断以及外设。
-
8 × 可编程I/O (PIO)状态机用于定制化外设支持 这个可以模拟很多外设,相当于一个小型的FPGA.
可以说这颗M0+具有很强大的性能,几乎可以和M4以及M7相媲美。
30 个 GPIO 引脚,其中 4 个可用作模拟输入 这颗芯片的DMA功能也是异常强大。详细可以参考芯片手册。
同时两颗芯片都支持SWD调试接口。
实现的功能
这次主要实现的是鼠标功能,
PC 鼠标功能
PC鼠标主要使用hid.py这个类
对于micropython中hid这个模块的编译和加载,可以参考下面的连接Plans for USB HID support?
也可以直接使用硬禾学堂官方提供的固件库firmware.uf2
对于micropython的HID库如何使用 可以参考ciruitpython的hid文档hid_user_guide
这边采用硬禾学堂提供的hid.py可以通过import来进行导入
import hid
m = hid.Mouse()
m.move(x,y)
m.press(m.BUTTON_LEFT)
m.release(m.BUTTON_LEFT)
制作鼠标一共用到上面几个函数,初始化Mouse, move是采用的相对路径进行一个鼠标平移的动作,根据x,y来相对平移,可以是负数,左键和右键采用press和release分别来判断按键按下还是释放。
遥感数据获取
遥感的电路图如图所示:
遥感数据是通过ADC模块获取的,引脚为28 29,获取值是16bit,数值在0~65535之间,
所以我们需要根据获取的ADC值来判断遥感的方向。代码如下所示
xAxis = ADC(Pin(29))
yAxis = ADC(Pin(28))
xValue = xAxis.read_u16()
yValue = yAxis.read_u16()
if xValue <1000:
x = -step
ab_x = ab_x - 5
elif xValue >40000:
x = +step
ab_x = ab_x + 5
if yValue <1000:
y = -step
ab_y = ab_y - 5
elif yValue >40000:
y = step
ab_y = ab_y + 5
左右按键获取
左右按键的原理图如图所示:
左右按键采用A,B按钮,通过PIN模块进行获取
详细代码如下所示
buttonB = Pin(5,Pin.IN, Pin.PULL_UP) #B
buttonA = Pin(6,Pin.IN, Pin.PULL_UP) #A
#获取按键值
buttonValueA = buttonA.value()
buttonValueB = buttonB.value()
按键值是0或者1,所以根据0或者1来判断是否按下左右键
if buttonValueA == 0:
btn_A_state = 1
m.press(m.BUTTON_RIGHT)
else:
if btn_A_state == 1:
btn_A_state = 0
m.release(m.BUTTON_RIGHT)
if buttonValueB == 0:
btn_B_state = 1
m.press(m.BUTTON_LEFT)
else:
if btn_B_state == 1:
btn_B_state = 0
m.release(m.BUTTON_LEFT)
如何绘制按键
板子上的LCD是240X240的st7789, 这款屏幕很多开发板都有使用。
电路图如图所示:
LCD初始化:
from machine import Pin, SPI,ADC
import st7789c
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),
#xstart=0,
#ystart=0,
rotation=0)
通过上面的初始化,LCD就初始化成功了。后面可以通过fill等函数可以对图片进行操作
tft.fill(st7789c.WHITE)这个是填充背景为白色
fill_rect 函数是用来画方形的:
tft.fill_rect(10,10,200,50,st7789c.GREEN)
可以参考上面的做法来画对应的矩形
图片可以通过jpg函数来进行填充
tft.jpg("mini.jpg", ab_x, ab_y, st7789c.FAST)
后面的ab_x和ab_y就是相对的路径
遇到的主要难题及解决方法如何
这边主要遇到的困难是在调整代码逻辑的时候,经常会遇到死机的情况,刚开始的时候,尝试将hid_mouse.py 改成main.py,觉得这样比较方便,能够上电之后就可以运行,但是后来调试的时候发现,突然有一次烧进去之后,怎么也起不来,后来才知道是代码写错了,进入死循环了出不来了,thonny也连接不上,重新烧入固件也不行(因为文件扇区没被擦除)
这个后来找了很久,想找个可以擦除整个FLASH 扇区的方法,最后问了群里才知道,需要烧入一个circuitpython的固件库,可以刷掉文件系统。去网上找了一个circuitpython的固件,刷进去,之后再刷micropython库,最后可以了。
未来的计划或建议
这次使用micropython做一个小东西,可以体现出,做产品效率之高,同样也体会到如果没有一个合适的固件的话,可能对于写micropython或者调试的话也是比较痛苦的。所以需要找到一个比较合适的固件,来完成项目。
这次也是因为工作比较忙的原因,没有能深入理解micropython的底层逻辑,下次可以尝试在pico c-sdk上面进行个lvgl的开发和应用。
参考