树莓派RP2040的简单利用
本项目使用了硬禾学堂“2022年寒假在家一起练”推出的“基于RP2040的嵌入式系统学习平台”,使用LCD显示屏,四向摇杆,Buzzer蜂鸣器和俩个按键,通过编程软件MicroPython设计了一个简单的“别碰方块”游戏。
实现目标:
-
利用板上的四向摇杆和按键设计一款“鼠标”
-
在240*240的LCD屏幕内可以通过该鼠标进行菜单选择和参数控。
-
用蜂鸣器播放音乐。
-
在LCD屏显示游戏,通过按键动作控制方块起跳。
- 通过USB端口可以控制PC屏幕上的光标移动和点击操作,行使电脑鼠标的功能
对于初学练手的我来说,完成这样的任务不能执着于深入了解单片机和python。我要做的是了解他们的一些基础功能,比如说怎么样在屏幕上画一个点?
有了这一个点,即使是牺牲运行速度,我也能画出一幅图片来。
import machine
import st7789 as st7789
from fonts import vga2_8x8 as font1
from fonts import vga1_16x32 as font2
st7789_res = 0
st7789_dc = 1
disp_width = 240
disp_height = 240
spi_sck=machine.Pin(2)
spi_tx=machine.Pin(3)
spi0=machine.SPI(0,baudrate=4000000, phase=1, polarity=1, sck=spi_sck, mosi=spi_tx)
display = st7789.ST7789(spi0, disp_width, disp_width,
reset=machine.Pin(st7789_res, machine.Pin.OUT),
dc=machine.Pin(st7789_dc, machine.Pin.OUT),
xstart=0, ystart=0, rotation=0)
#-----------------------------通过以上代码可以实现用像素绘制一些简单图形-------------------------
import math
def p(x,y):
display.pixel(x,y,st7789.color565(0xff,0xff,0xff))
rule=4*3.14/240
for i in range(240):
p(i,int(120+50*math.sin(rule*i)))
经过四处查阅,尤其要感谢交流群里的老师,我了解到了画图需要的代码,能让屏幕按我的心意亮起来,任务已经完成了一大半!
(全部代码在百度网盘: https://pan.baidu.com/s/15OZSKgfkTptf2Jg-7k8zqw?pwd=1su7 提取码: 1su7 )
我还总结了四向摇杆,“A”,“B”按键的人机交互(交互.py)。有了这些代码,思路也就有了,我可以做一个简单的像素小游戏,其次可以实现鼠标在PC端和单片机上的全部功能,可以为游戏做一个菜单,我还可以把蜂鸣器(Buzzer -蜂鸣器)用起来,唱一首歌。
其实在LCD上的鼠标实现方式和在PC端上的实现方式是有很大的不同的,但对鼠标的控制很多想法都是想通的,比如如何对ADC函数获得的波过滤,达到不让鼠标一直晃动的目的?通过实践观察发现,摇杆不动的时候,函数值的变化范围最多只有600,所以我想到了通过下面的判断来实现这一功能。
if xValue-x0>1000 or xValue-x0<-1000 or yValue-y0>1000 or yValue -y0<-1000:
m.move((xValue-x0)//2000,(yValue-y0)//2000)
其次是LCD上鼠标的绘制,我采用的办法是以一个点来确定鼠标的位置,然后根据这个点画线。这样,鼠标的移动也就是这个点的移动了。最后就是如何判断按键的时候到底按的是哪个键呢?我们可以记录选项字体的范围,然后判段按键时的鼠标位置是否在范围里就可以了。
display.text(font2, "Music_one", 55, 95)
display.text(font2, "Music_two", 55, 125)
if a.value():
if mouse_x>50 and mouse_x<150 and mouse_y>90 and mouse_y<120:
mu=1
break
elif mouse_x>50 and mouse_x<150 and mouse_y>130 and mouse_y<150:
mu=2
break
不过用点一个一个地画,对于这样的单片机来说刷新确实很吃力。所以就要想办法节约资源,我在屏幕刷新这一步上想到了俩种方法,一种是全屏刷新(mouse-01.py),另一种想法是局部覆盖(mouse-02.py),俩种方法各有千秋,在后面的代码中也都有自己的用处。
在“别碰方块”的游戏中,碰撞逻辑和起跳对我来说是另一个难点,是我从一本书中了解到了解决的办法(《C和C++游戏趣味编程》)的。
if a.value():
square_vy=-26
if rect_x1 <= square_0x + square_side//2 and rect_x1 + rect_width1 >= square_0x - square_side//2 and disp_height - rect_height1 <= square_0y + square_side//2:
display.text(font2, "Lose", 85, 125)
sleep(10)
led.value(0)
在播放音乐的时候,我遇到了当时难以理解的事情,那就是音乐停下后往往都是蜂鸣器刺耳的声音,让我很是无奈,后来慢慢理解到,原来是强行中断音乐,但蜂鸣器的引脚却任然处于开的状态,所以会有刺耳的长鸣,我模仿其他引脚的控制函数,在结束音乐后人为地把引脚关掉,这样就不会再有刺耳的声音了。
if mu==1:
display.fill(st7789.BLACK)
display.text(font2, "Music_one", 85, 95)
while True:
mySong1.tick()
sleep(0.04)
if b.value():
song=Pin(23,Pin.OUT)
song.value(0)
break
如何上手单片机,方法很多:看书,看教程,请教其他人,这些都是可行的。但最重要的是学习的热情,以及由之而来的动力。正是因为单片机能让我们按自己的想法实现很多事情,所以我们才有了探索的动力。
主要困难:Python对我来说是一门新语言,对MicroPython功能的不熟悉,而且受其语言本身运行速度较慢的影响,游戏的质量很难做到让人满意。但关于C游戏编程,我已经能做到在PC端编码“贪吃蛇”,“推箱子”,“十步万度”,“十字消除”以及“见缝插针”等游戏(源代码已包含在压缩包)。
所以下一步的目标就是学习用C/C++进行RP2040的编程,之所以起初没用C编程,而选择了MicroPython是因为是因为对环境的配置不太了解,比如画图用的EasyX库该如何导入这一问题比较难办,还望有经验的前辈指导一二。
未来计划:在解决了运行速度和编译环境的基础上,就可以尝试将更多的游戏移植到RP2040游戏机上。而且我还有个计划,我们学院有一间小图书馆,缺一个管理系统:我是不是可以做一个管理系统移植到这个游戏机上呢?