引言
手里一直有两块RaspberryPi ZeroW板子闲置,最近想玩起来,但最基本的一台微型电脑,除了主板之外,还需要输入输出设备。我对于微型掌机(MINI型的显示/输入)比较感兴趣,于是干脆买了一款基于树莓派的游戏机的配件Game_HAT。该配件配有3.5寸液晶屏可用于输出显示,有一个4方向的遥感按键以及N个独立按键可用于基本输入。配件提供的是游戏系统,我不感兴趣,我希望在官方RaspberryPi的系统中,编写一个驱动程序,将4向摇杆按键和2个独立按键模拟成鼠标的功能。而编写内核驱动稍微复杂,于是决定使用Python来实现。
硬件准备
根据Game_HAT资料,其屏幕是HDMI接口,因此将RaspberryPi ZeroW插到套件排座上,然后通过MINI HDMI转标准HDMI直接连接屏幕即可。至于按键连接的管脚编号,Game_HAT也已给出,本驱动目前只用到四向摇杆+Y/B按键。
排针引脚编号 | 功能 | 对应引脚编号(BCM和WiringPi两种) |
---|---|---|
29 | UP | BCM=5,WPI=21 |
31 | DOWN | BCM=6,WPI=22 |
33 | LEFT | BCM=13,WPI=23 |
35 | RIGHT | BCM=19,WPI=24 |
38 | Y | BCM=20,WPI=28 |
37 | A | BCM=26,WPI=25 |
软件准备
树莓派已使用官方工具烧写Raspberry Pi OS Lite(基于Debian Buster(10)),顺便配置好了WIFI、SSH
SSH使用raspberrypi.local作为主机地址,用户名:pi,密码:(烧写时配的),进行登录
如过SSH连不上,可尝试将SD卡接入电脑,在boot分区下,新建“ssh”文件,将SSH开启
已修改镜像源为国内清华镜像,树莓派注意需要修改两个文件:
编辑 /etc/apt/sources.list 文件 (通常Linux只需要修改这个文件)
1
2
3
4#deb http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free rpi
deb https://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ buster main non-free contrib rpi
# Uncomment line below then 'apt-get update' to enable 'apt-get source'
#deb-src http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free rpi编辑 /etc/apt/sources.list.d/raspi.list 文件
1
2
3
4deb https://mirrors.tuna.tsinghua.edu.cn/raspberrypi/ buster main
#deb http://archive.raspberrypi.org/debian/ buster main
# Uncomment line below then 'apt-get update' to enable 'apt-get source'
#deb-src http://archive.raspberrypi.org/debian/ buster main已安装轻量级图形界面LXDE,可参考教程(PI ZeroW性能较低,官方桌面太卡了,选择Lite OS + LXDE的组合方式)
已配置好HDMI屏幕分辨率匹配屏幕(480×320)
方法:
1
sudo nano /boot/config.txt
在文件末尾,增加
1
2
3
4
5hdmi_group=2
hdmi_mode=87
hdmi_pixel_freq_limit=20000000
hdmi_cvt 480 320 60 6 0 0 0
hdmi_drive=1已通过命令(sudo raspi-config),配置安装VNC,电脑通过VNC Viewer,通过主机名raspberrypi.local可以进行桌面远程
SSH终端软件
SSH终端软件,我选择的是开源的WindTerm,这个软件可以直接看到Linux终端上的文件列表,并且可以直接右键选择编辑器打开,可以很方便的在Windows上编辑Linux终端的文件,修改保存之后也可以直接上传回Linux终端。
Python库安装
安装rpi.gpio库(树莓派官方系统应该已经默认安装了)
1
sudo apt install python3-rpi.gpio
安装uinput库(用于模拟鼠标设备)
1
sudo apt install python3-uinput
安装distutils库,uinput会依赖该库
1
sudo apt install python3-distutils
配置uinput模块在boot阶段载入
编辑 /etc/modules文件,在文件末尾增加“uinput”
1
sudo nano /etc/modules
1
2
3
4
5
6# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.
uinput
驱动源码
脚本文件keydriver_multiprocess.py源码:
1 | import multiprocessing |
测试运行(必须使用sudo执行):
1 | sudo python3 keydriver_multiprocess.py |
主要代码都做了注释解释,其中关键几点是:
- 为每个按键都创建了一个进程(非线程),用于检测按键是否有动作;同时还为方向、左右键的动作更新到uinput分别创建了两个进程;使用了两个队列,来建立按键检测进程和uinput更新进程之间的数据通信。
- 所有进程都要配置为守护进程,使得主进程结束时,可以将所有进程同步结束,否则可能出现Python脚本已退出,但创建的进程还在运行的情况。
- 所有进程都使用Pending等待的方式等待事件发生(按键检测进程等待IO边沿发生,更新设备状态进程等待队列有数据),才执行代码,以便在无按键动作时尽可能不占用CPU资源
配置开启自启动
若开机自动运行该脚本,则可配置开机自启动。
将脚本拷贝到/usr目录下
在/usr下建立一个pyscript目录,专门存放python脚本,以后调试好的python脚本都放这里
1
cp keydriver_multiprocess.py /usr/pyscript/
编辑 /etc/rc.local 文件
1
sudo nano /etc/rc.local
在 exit 0 前添加执行语句
1
2
3
4
5
6...
...
/usr/bin/python3 /usr/pyscript/keydriver_multiprocess.py
exit 0
效果演示
脚本运行的情况下,若无按键动作,CPU占用率很低。
视频演示:
小结
本文使用Python在树莓派上编写了一个基础按键驱动,实现了四方向摇杆按键+2个独立按键模拟鼠标的功能。该驱动程序使用Python编写,实现简单,调试方便。使用多进程、队列通信、等待事件触发的思想,可以实现在按键动作时快速响应,而无按键动作时占用极低的CPU资源。