时不时地,我会怀念80年代末和90年代童年时玩过的视频游戏。虽然我的大多数旧电脑和游戏机早已不复存在,但我的树莓派可以满足我对复古游戏的需求。我喜欢 Raspbian 中包含的简单游戏,并且开源的 RetroPie 项目帮助我将树莓派变成了一台高级复古游戏机。
但是,为了获得更真实的体验,就像“过去的日子”一样,我需要一个游戏手柄。市场上有很多 USB 游戏手柄和操纵杆的选择,但作为一名开源爱好者、创客和工程师,我更喜欢走艰难的路。因此,我制作了自己的简单开源硬件游戏手柄,我将其命名为 ANAVI Play pHAT。我将其设计为树莓派的附加板,使用了一个 EEPROM 和一个我创建的设备树二进制覆盖来映射按键。
获取游戏手柄按钮和 EEPROM
有各种各样的游戏手柄可供购买,其中一些非常复杂。但是,使用我创建的设计,制作一个类似于标志性的 NES 控制器的游戏手柄并不难。
该游戏手柄使用八个“瞬时”按钮(即,仅在按下时才激活的开关):四个用于移动的轻触开关(上、下、左、右),两个用于 A 和 B 的轻触按钮,以及两个用于选择和开始的较小轻触按钮。我使用了通孔轻触开关:六个 6x6x4.3 毫米开关用于移动以及 A 和 B 按钮,以及两个 3x6x4.3 毫米开关用于开始和选择按钮。
虽然游戏手柄的主要目的是玩复古游戏,但附加板足够大,可以包含家庭自动化功能,例如监控温度、湿度、光线或气压,这些功能可以在不玩游戏时使用。我添加了三个插槽,用于将 I2C 传感器连接到物理引脚 3 和 5 上的主 I2C 总线。
硬件设计中最有趣和最重要的部分是 EEPROM(电可擦除可编程只读存储器)。通孔安装的 EEPROM 更容易在面包板上刷写并焊接到游戏手柄上。MagPi 杂志上的一篇文章推荐使用 CAT24C32 EEPROM;如果该型号不可用,请尝试查找具有类似技术规格的型号。2014 年之后发布的所有树莓派型号和版本(树莓派 B+ 及更高版本)在物理引脚 27 和 28 上都有辅助 I2C 总线。
一旦拥有了这些硬件,请使用面包板检查其是否有效。
创建印刷电路板
下一步是创建印刷电路板 (PCB) 设计并进行制造。作为一名开源爱好者,我相信应该使用免费和开源软件来创建开源硬件。我依赖于 KiCad,这是一款在 GPLv3+ 许可下提供的电子设计自动化 (EDA) 软件。KiCad 可以在 Windows、MacOS 和 GNU/Linux 上运行。(我在 Ubuntu 18.04 上使用 KiCad 5 版本。)
KiCad 允许您创建具有最多 32 个铜层加上 14 个固定用途技术层的 PCB。它还具有集成的 3D 查看器。它正在积极开发中,包括 CERN 开发人员的许多贡献,并用于工业应用;例如,Olimex 使用 KiCad 设计具有多层的复杂 PCB,例如其 TERES-I DIY 开源硬件笔记本电脑中的 PCB。
KiCad 工作流程包括三个主要步骤
- 在原理图布局编辑器中设计原理图
- 在 PCB 布局编辑器中绘制边缘切割线、放置元件并布线
- 导出 Gerber 和钻孔文件以进行制造
如果您以前没有设计过 PCB,请记住存在陡峭的学习曲线。请阅读 KiCad 提供的示例和用户指南,了解如何使用原理图和 PCB 布局编辑器。(如果您不想从头开始做所有事情,您可以直接克隆我在 GitHub 存储库中的 ANAVI Play pHAT 项目。)

在 KiCad 的原理图布局编辑器中,将树莓派的 GPIO 连接到按钮,将传感器插槽连接到主 I2C,将 EEPROM 连接到辅助 I2C。为每个组件分配适当的封装。执行电气规则检查,如果没有错误,则生成网络表,该表描述了电子电路的连接性。
打开 PCB 布局编辑器。它包含多个层。读取网络表。所有组件和走线必须位于正面和背面铜层(F.Cu 和 B.Cu)上,并且板的形状必须在 Edge.Cuts 层中创建。任何文本,包括按钮标签,都必须位于丝印层上。

最后,导出 Gerber 和钻孔文件,您将发送给生产 PCB 的公司。Gerber 格式是 PCB 的事实上的行业标准。它是一种开放的 ASCII 矢量格式,用于 2D 二进制图像;简单来说,它就像 PCB 制造的 PDF。
有许多公司可以制造像游戏手柄这样简单的双层板。对于一些原型,您可以依靠美国的 OSHPark 或 欧洲的 Aisler。还有很多中国制造商,如 JLCPCB、PCBWay、ALLPCB、Seeed Studio 等等。或者,如果您不想麻烦 PCB 制造和采购组件,您可以从 Crowd Supply 订购 ANAVI Play pHAT 制作套件,并自行焊接所有通孔组件。
理解设备树
设备树是一种用于描述硬件组件的软件数据结构的规范。它的目的是允许编译后的 Linux 内核处理更广泛的架构系列中的各种不同的硬件配置。引导加载程序将设备树加载到内存中并将其传递给 Linux 内核。
设备树包括三个组件
- 设备树源 (DTS)
- 设备树 Blob (DTB) 和覆盖 (DTBO)
- 设备树编译器 (DTC)
DTC 从文本源创建二进制文件。设备树覆盖允许将中央 DTB 覆盖在设备树上。覆盖包括许多片段。
几年来,所有新的片上系统 (SoC)(包括所有树莓派型号和版本中的 Broadcom SoC)都需要设备树。使用树莓派流行的 Raspbian 发行版中的默认引导加载程序,可以使用关键字 device_tree= 在可引导 microSD 卡的 FAT 分区上的配置文件 (config.txt) 中设置 DTO。
自 2014 年以来,树莓派的引脚头已扩展到 40 个引脚。引脚 27 和 28 专用于辅助 I2C 总线。这样,DTBO 可以从连接到这些引脚的 EEPROM 自动加载。此外,其他系统信息可以保存在 EEPROM 中。此功能是树莓派基金会针对任何树莓派 HAT(顶部附加的硬件)附加板的要求之一。在 Raspbian 和其他用于树莓派的 GNU/Linux 发行版上,启动后可以在 /proc/device-tree/hat/ 的用户空间中看到来自 EEPROM 的信息。
在我看来,设备树是过去十年中 Linux 生态系统中添加的最令人着迷的功能之一。创建设备树 Blob 和覆盖是一项高级任务,需要一些背景知识。但是,可以为树莓派附加板创建一个设备树二进制覆盖并将其刷写到适当的 EEPROM 上。设备二进制覆盖定义了游戏手柄的每个按键的 Linux 键代码。结果是一个树莓派游戏手柄,其按键在启动 Raspbian 后即可使用。
创建 DTBO
为游戏手柄创建设备树二进制覆盖有三个主要步骤
- 使用基于 Linux 键代码的按键映射创建设备树源
- 使用设备树编译编译设备树二进制覆盖
- 创建 .eep 文件并使用树莓派基金会提供的开源工具将其刷写到 EEPROM 上
Linux 键代码在文件 /usr/include/linux/input-event-codes.h 中定义。设备源文件应描述哪个树莓派 GPIO 引脚连接到哪个硬件按钮,以及按下按钮时应触发哪个 Linux 键代码。在此游戏手柄中,GPIO17(引脚 11)连接到向右的轻触按钮,GPIO4(引脚 7)连接到向左的轻触按钮,GPIO22(引脚 15)连接到向上的轻触按钮,GPIO27(引脚 13)连接到向下的轻触按钮,GPIO5(引脚 29)连接到开始,GPIO6(引脚 31)连接到选择,GPIO19(引脚 35)连接到 A,GPIO26(引脚 37)连接到 B。
请注意,GPIO 编号和引脚在接头上的物理位置之间存在差异。为方便起见,所有引脚都位于树莓派 40 针接头的第二行。这种方法使在 KiCad 中布线印刷电路板更容易。
游戏手柄的整个设备树源可在 GitHub 上找到。例如,以下是一个简短的代码片段,演示了如何将对应于树莓派上物理引脚 11 的 GPIO17 映射到向右的轻触按钮
button@17 {
label = "right";
linux,code = <106>;
gpios = <&gpio 17 1>;
};
要在树莓派上直接编译 DTS,请通过在终端中执行以下命令在 Raspbian 上安装设备树编译器
sudo apt-get update
sudo apt-get install device-tree-compiler
运行 DTC 并提供输出 DTBO 的名称和源文件的路径作为参数。例如
dtc -I dts -O dtb -o anavi-play-phat.dtbo anavi-play-phat.dts
树莓派基金会提供了一个 GitHub 存储库,其中包含 HAT 的机械、硬件和软件规范。它还包括三个非常方便的工具
- eepmake: 从带有设置的文本文件创建 .eep 文件
- eepdump: 有助于调试,因为它将二进制 .eep 文件转储为人类可读的文本
- eepflash: 将 .eep 二进制图像写入 EEPROM 或从 EEPROM 读取
eeprom_settings.txt 文件可以用作模板。树莓派基金会 和 MagPi 杂志 有帮助的文章和教程,因此我不会过多赘述。正如我上面所写,推荐的 EEPROM 是 CAT24C32,但可以用任何其他具有相同技术规格的 EEPROM 替换。使用带有八针、通孔、双列直插 (DIP) 封装的 EEPROM 更便于爱好者刷写,因为可以使用面包板完成。以下示例命令使用树莓派 GitHub 存储库中的 eepmake 工具创建一个准备好在 EEPROM 上刷写的文件
./eepmake settings.txt settings.eep anavi-play-phat.dtbo
在开始刷写之前,请确保 EEPROM 已正确连接到 Raspberry Pi 上的主 I2C 总线(引脚 3 和 5)。(您可以查阅上面链接的 MagPi 杂志文章,其中讨论了接线原理图。)然后运行以下命令,并按照屏幕上的说明将 .eep 文件刷写到 EEPROM 上。
sudo ./eepflash.sh -w -f=settings.eep -t=24c32
在将 EEPROM 焊接到印刷电路板之前,请将其移动到面包板上的辅助 I2C 总线,并对其进行测试以确保其按预期工作。如果在面包板上测试 EEPROM 时发现任何问题,请更正设置文件,将其移回主 I2C 总线,然后再次刷写。
测试游戏手柄
现在是好玩的部分了!是时候使用 Raspbian 测试附加板了,您可以从 RaspberryPi.org 下载 Raspbian。启动后,打开终端并输入以下命令
cat /proc/device-tree/hat/product
cat /proc/device-tree/hat/vendor
输出应该类似于这样

如果是,恭喜!已成功读取 EEPROM 中的数据。
下一步是验证 Play pHAT 上的按键是否已正确设置并正常工作。在终端或文本编辑器中,按下八个按钮中的每一个,并验证它们是否按配置的方式工作。
最后,是时候玩游戏了!默认情况下,Raspbian 的桌面包含 Python 游戏。从应用程序菜单启动它们。选择一个音频输出并从列表中选择一个游戏。我最喜欢的是 Wormy,一个类似贪吃蛇的游戏。作为一名前 Symbian 移动应用程序开发人员,我发现玩 Wormy 让我想起了诺基亚的光辉岁月。
使用 RetroPie 进行复古游戏

Raspbian 非常棒,但 RetroPie 为复古游戏爱好者提供了更多功能。它是一个针对复古游戏优化的 GNU/Linux 发行版,并结合了开源项目 RetroArch 和 Emulation Station。它适用于 Raspberry Pi、Odroid C1/C2 以及运行 Debian 或 Ubuntu 的个人电脑。它提供了加载 ROM 的模拟器——游戏卡带的数字版本。请记住,由于版权问题,RetroPie 中不包含任何 ROM。启动 RetroPie 后,您必须 找到合适的 ROM 并将它们复制到 Raspberry Pi。
开源硬件游戏手柄在 RetroPie 的菜单中工作正常,但我发现启动某些游戏和模拟器后,按键会失效。经过调试,我找到了一个解决方案来确保它们在游戏模拟器中工作:添加一个 Python 脚本来额外进行按键的软件模拟。该脚本可在 GitHub 上获得。以下是如何获取它并在 RetroPie 上安装 Python
sudo apt-get update
sudo apt-get install -y python-pip
sudo pip install evdev
cd ~
git clone https://github.com/AnaviTechnology/anavi-examples.git
最后,将以下行添加到 /etc/rc.local,以便在 RetroPie 启动时自动执行
sudo python /home/pi/anavi-examples/anavi-play-phat/anavi-play-gamepad.py &
就这样!按照这些步骤操作后,您可以创建一个完全开源的硬件游戏手柄作为任何带有 40 针接头的 Raspberry Pi 型号的附加板,并在 Raspbian 和 RetroPie 中使用它!
接下来是什么?
将自由和开源软件与开源硬件相结合既有趣又不困难,但需要大量时间。在业余时间创建开源硬件游戏手柄后,我在 Crowd Supply 上发起了一个小型的众筹活动,以便在我家乡保加利亚普罗夫迪夫进行小批量生产。开源硬件协会已将 ANAVI Play pHAT 认证为 BG000007 下的开源硬件项目。甚至保护电路板免受灰尘侵害的亚克力外壳也是使用自由和开源软件 OpenSCAD 创建的开源硬件。

如果您喜欢阅读本文,我鼓励您尝试使用 KiCad 为 Raspberry Pi 创建自己的开源硬件附加板。如果您的业余时间不够,您可以订购 ANAVI Play pHAT 制作套件,拿起您的烙铁,然后组装通孔元件。如果您不擅长使用烙铁,您可以直接订购一个完全组装好的版本。
祝大家复古游戏愉快!下次有人恼怒地问你从玩老式电脑游戏中可以学到什么时,告诉他们关于 Raspberry Pi、开源硬件、Linux 和设备树的知识。
5 条评论