RRoy 发表于 2023-3-23 11:23:09

超详细教程!自制一个Arduino NES(红白机)游戏机!





目前大多数NES模拟器需要使用某种C编译器(例如esp-idf)手动进行命令行构建,这对于初学者来说是一个很大的障碍。

这周就和大家分享如何使用Arduino IDE做一个便携式NES(红白机)游戏机。
https://dfrobot.loll.cc/video/arduino-nofrendo_change_game-%5BckBqONHllAg%5D.mp4

NES游戏机是一款由任天堂公司于1985年发布的家用电子游戏机。NES是“Nintendo Entertainment System”的缩写,也被称为“红白机”。该游戏机在1980年代和1990年代风靡全球,并为游戏业界的发展做出了重要贡献。

NES游戏机使用卡带作为游戏载体,玩家可以通过插入卡带来运行各种游戏。该游戏机的手柄设计也非常经典,包括方向键、A、B两个按钮和选择、开始两个功能键。

许多经典游戏如《超级马里奥兄弟》、《塞尔达传说》、《龙与地下城》、《银河战士》等都是在NES游戏机上首次发布的。即使在今天,许多玩家仍然喜欢玩NES游戏机上的经典游戏,而该游戏机的影响力也一直延续至今。


材料清单

[*]4.0 英寸 ST7796S SPI LCD 模块
[*]四个 400 孔面包板
[*]TTGO T8 v1.7 ESP32 开发板
[*]MAX98357 I2S 放大器模块
[*]PCB安装迷你喇叭
[*]PSP模拟摇杆模块
[*]六个按钮模块


步骤1:Nofrendo是什么?
Nofrendo是一个很好的NES模拟器,它可以在较老的奔腾系统上全速运行,具有不错的声音支持和良好的兼容性。

Nofrendo是由Matthew Conte在上个世纪开发的,它可以在Windows、Unix和BeOS上运行。由于实现已经泛化以支持不同的平台,许多开发人员开始基于它开发其他平台的NES模拟器。

参考资料:

http://www.baisoku.org

https://www.zophar.net/nes/nofrendo.html

https://github.com/adafruit/nofrendo_arcada

https://github.com/espressif/esp32-nesemu

步骤2:Arduino-nofrendo
Github用户rickyzhang82在2018年将Nofrendo原始源代码推送到Github。我已经fork了该仓库,并将其转换为兼容Arduino库的布局。只需实现osd.h中声明的所有函数即可使其工作。

理论上,如果有足够的RAM和处理能力,这个库可以在任何Arduino平台上使用。由于Espressif已经证明ESP32可以运行Nofrendo,所以我基于他们的示例代码,在examples文件夹下开发了一个esp32-nofrendo示例。

参考资料:

https://github.com/rickyzhang82/nofrendo

https://github.com/moononournation/arduino-nofrendo

步骤3:显示选项
为了支持尽可能多的显示变化,我将显示实现更改为使用Arduino_GFX。现在甚至支持像ST7796这样的大型4英寸320x480显示屏。

以下是Arduino_GFX支持的可以适用于Nofrendo分辨率的显示变化:

[*]HX8347C 240 x 320
[*]HX8347D 240 x 320
[*]HX8352C 240 x 400 (16:9)
[*]HX8357B 320 x 480
[*]ILI9341 240 x 320
[*]ILI9481 320 x 480 18位色彩
[*]ILI9486 320 x 480 18位色彩
[*]ILI9488 320 x480 18位色彩
[*]M5Stack 240 x 320
[*]R61529 320 x 480
[*]ST7789 240 x 320
[*]ST7789 240 x 240
[*]ST7796 320 x 480

注意:

320 x 480显示需要将原始256 x 240分辨率裁剪为240 x 214,然后放大到480 x 320。

宽度放大两倍,高度放大1.5倍,每2个原始线条绘制3条线。第三条线可以重复第二条线,也可以简单地保留第三条线的背景色。

详细实现可在display.cpp中找到。

步骤4:音频选项
目前arduino-nofrendo支持(实际上是arduino-esp32支持)2种音频输出方法:

[*]内置DAC - ESP32具有两个8位DAC(数字模拟转换器)通道,分别连接到GPIO25(通道1)和GPIO26(通道2),由于输出非常弱,因此仍需要额外的音频放大器用于扬声器输出。
[*]外部I2S DAC模块 - 只需连接3个信号线和电源到I2S放大器模块,它可以在同一个模块中完成DAC和音频放大器的工作。

注意:

内置DAC仅具有8位分辨率,并且存在过多的静态噪声(杂音),通过使用外部的 I2S 放大模块可以降低这种静态噪声的影响(因为外部模块可以提供更好的信噪比和动态范围。)

步骤5:控制器选项http://static.video.qq.com/TPout.swf?vid=wxv_2851229472761593860&1314.swf

目前arduino-nofrendo支持3种类型的控制器:

[*]GPIO输入 - 简单地将每个控制器按钮映射到一个GPIO,箭头键也有一个选项映射到一个二轴模拟摇杆
[*]I2C M5Stack CardKB 迷你键盘 https://m5stack.com/products/cardkb-mini-keyboard
[*]I2C BBQ10键盘 https://github.com/arturo182/BBQ10KBD

即将支持:

[*]更多I2C设备,例如I2C游戏手柄
[*]蓝牙设备,例如蓝牙游戏手柄和蓝牙键盘

注意:

默认的arduino-esp32 I2C接口连接到GPIO 21(SDA)和22(SCL)。

步骤6:文件系统选项
Nofrendo在文件系统中存储3种类型的文件:

[*]ROM文件*.nes - 游戏
[*]游戏存档文件*.sav - 当你在游戏中保存时,数据备份到此文件
[*]状态文件*.ss - 当你使用Nofrendo保存状态功能时,数据存储在这些文件中

目前arduino-nofrendo支持(实际上是arduino-esp32支持)3种类型的文件系统:

[*]SPIFFS - 通常是ESP32闪存的最后一个分区
[*]SD - Arduino标准SPI模式SD卡接口
[*]SD_MMC - 原生1位或4位SD模式SD卡接口

注意:

选SPIFFS测试是最简单的方法,但在SPIFFS中备份存档和状态文件比较困难,SD或SD_MMC更适合长期使用。另外,如上面视频演示,你可以将SD卡当作游戏卡,只需更换SD卡即可更换游戏。

步骤7:软件准备Arduino IDE
如果你尚未安装Arduino IDE,请下载并安装:

https://www.arduino.cc/en/main/software
ESP32支持
按照安装说明添加ESP32支持,如果尚未安装:

https://github.com/espressif/arduino-esp32

注意:请使用arduino-esp32版本1.0.6进行此项目,较新版本可能无法成功编译
Arduino ESP32 filesystem uploader
按照安装步骤安装Arduino ESP32 filesystem uploader,如果没有安装的话:

https://github.com/me-no-dev/arduino-esp32fs-plugin
Arduino_GFX库
下载最新的Arduino_GFX库:(点“Clone or Download”->“Download ZIP”)

https://github.com/moononournation/Arduino_GFX

在Arduino IDE中导入库。(Arduino IDE“项目”菜单->“包含库”->“添加.ZIP库”->选择下载的ZIP文件)
Arduino Nofrendo库
下载最新的Arduino Nofrendo库:(点“Clone or Download”->“Download ZIP”)

https://github.com/moononournation/arduino-nofrendo

同样在Arduino IDE中导入库。(Arduino IDE“项目”菜单->“包含库”->“添加.ZIP库”->选择下载的ZIP文件)

步骤8:面包板原型


在制作你自己的便携式Arduino NES控制台最终版本之前,让我们先用面包板原型进行一个PoC(概念验证)。

步骤9:面包板改造






4寸LCD是一个比较大的尺寸,我们需要把四个400孔面包板组合在一起。不过,8个电源总线太多了,我们去掉其中的6个,只保留2个就足够了。

步骤10:TTGO T8 V1.7改造




将四个400孔面包板组合在一起可以放下4寸LCD,但仍然没有足够的剩余空间来放一块ESP32开发板。因此,我们需要将ESP32开发板的一部分隐藏在LCD下方。同时,将线路也隐藏在LCD下方使其更整洁。

但我发现TTGO T8 V1.7的3D天线无法放LCD下方。由于NES控制台不需要互联网接入,我就直接把它拆了……

注意:

[*]以后仍然可以通过IPEX连接器将WiFi信号引导到外部天线
[*]蓝牙设备连接也需要天线

步骤11:LCD改造








[*]焊接SD引脚接头
[*]可选操作:重新焊接所有LCD引脚,使引脚稍微伸长到面包板
[*]插入额外的塑料隔离片,在面包板和LCD之间预留更多空间

步骤12:固定模拟摇杆


带有引脚的模拟摇杆一侧可以非常好地固定在面包板上,但另一侧需要一些额外的引脚才能固定在面包板上。



步骤13:I2S放大器模块改造




I2S放大器模块的扬声器连接器不是2.54毫米间距(面包板孔的间距大小),需要稍微弯曲引脚接头以方便焊接。

步骤14:布局设计




在实际的面包板布线之前,我们首先先设计所有组件的布局,并仔细检查所有组件的位置是否与LCD冲突。

步骤15:引脚映射设计


这一步是可选的,只是为了使线路更加整洁(由于所有的线路都隐藏在LCD后面,这并不是必要的)。

大多数ESP32接口可以重新映射到任何GPIO引脚,除了SD_MMC。由于TTGO T8 v1.7已经内置了与SD_MMC接口连接的SD卡插槽,我想重用那些引脚连接到LCD SD卡插槽。

我在开发板下方使用了一些面包板线将一些GPIO重定向到其他面包板条,让整个布局看起来更加整洁:

[*]
模拟摇杆引脚GPIO 34和35至左下角
[*]
SD_MMC引脚GPIO 13、15、2和14至右上角
[*]
开始和选择按钮引脚GPIO 26和27至右下角
[*]
3v3连接至2个电源条
[*]
GND连接至电源条
[*]
模拟摇杆引脚 GPIO 34 和 35 连接到左下方
[*]
SD_MMC 引脚 GPIO 13、15、2 和 14 连接到右上角
[*]
开始和选择按钮引脚 GPIO 26 和 27 连接到右下角
[*]
3v3 连接到两个电源插头
[*]
GND 连接到电源插头

注意:

SPI显示器通常需要连接7个GPIO引脚,它们是CS、RESET、D/C、SCK、MOSI、MISO和LED。为了把GPIO的使用次数减少到3次,进行了一些安排:

[*]CS接地,表示始终使能
[*]复位连接到ESP32复位,LCD在ESP32复位时复位
[*]MISO不连接,无需从LCD读取数据
[*]LED连接至VCC,LCD背光始终100%开启

步骤16:面包板布线




以下是连接汇总:
ESP32
VCC -> LCD VCC & LED, I2S放大器模块VCC,摇杆VCC
GND -> LCD GND & CS, I2S放大器模块GND,摇杆GND,所有按钮GND
RST -> LCD RST
GPIO 34 -> 摇杆上下模拟
GPIO 35 -> 摇杆左右模拟
GPIO 32 -> LCD D/C
GPIO 33 -> LCD MOSI
GPIO 25 -> LCD SCK
GPIO 26 -> 按钮开始
GPIO 27 -> 按钮选择
GPIO 23 -> 按钮X
GPIO 18 -> 按钮Y
GPIO 5 -> 按钮A
GPIO 4 -> 按钮B
GPIO 14 -> SD SCK
GPIO 13 -> SD CS
GPIO 15 -> SD MOSI
GPIO 2 -> SD MISO
GPIO 22 -> I2S放大器模块BCLK
GPIO 21 -> I2S放大器模块WCLK(或称LRC)
GPIO 19 -> I2S放大器模块DOUT(或称DIN)
I2S放大器模块GAIN -> 100欧姆电阻 -> GND(可选15 dB增益)
I2S放大器模块+ve -> 扬声器+ve
I2S放大器模块-ve -> 扬声器-ve
步骤17:可选电池


TTGO T8 v1.7开发板内置了锂电池充电和稳压电路。连接一个锂电池可以让游戏机变得更便携式,但对于原型设计来说并不是必要的。

面包板背后有一个很大的平面,可以放置一个非常大的锂电池。

步骤18:程序




操作步骤如下:

[*]连接设备的 USB 线
[*]打开 Arduino IDE
[*]打开 esp32-nofrendo 示例代码("文件" -> "示例" -> "arduino--nofrendo" -> "esp32-nofrendo")
[*]检查 hw_config.h 和 display.cpp 中的配置参数,默认参数已设置为此面包板的
[*]按下 Arduino IDE 的 "上传" 按钮

注意:

有时需要拆卸 SD 卡才能成功上传。

步骤19:ROM

https://dfrobot.loll.cc/video/arduino-nofrendo_default_ROM_when_no_ROM_file_found-%5B7kNzhut69Tc%5D.mp4


如果你手头没有任何 NES rom 文件,可以在网上找到许多自制的 NES rom,例如:

http://www.nesworld.com/article.php?system=nes&data=neshomebrew

我已经在“最佳自制任天堂娱乐系统游戏”中选择了一个名为“Chase”的简单游戏,用于esp32-nofrendo示例。

注意:

还推荐一个名为 "BLADE BUSTER" 的自制射击游戏,但是 rom 大小不能适用于没有 PSRAM 的开发板。(nofrendo 需要将 rom 文件加载到内存中)

步骤20:上传 ROM 文件


默认的 hw_config.h 参数设置为使用 SD 文件系统,只需将 ROM 文件*.nes复制到 SD 卡中并插入即可使其正常工作。

如果更改为使用 SPIFFS 文件系统,则 esp32-nofrendo 示例已经在 data 文件夹中包含了一个 "Chase.nes" ROM 文件。

只需在 Arduino IDE 中选择 "工具" 菜单 -> "ESP32 Sketch Data Upload" 将 ROM 文件上传到 ESP32 SPIFFS。

你也可以将 ROM 文件复制到数据文件并上传。

注意:

此时,esp32-nofrendo 示例将找到第一个 *.nes 文件并加载它。

步骤21:状态保存和加载

https://dfrobot.loll.cc/video/arduino-nofrendo_save_and_load_status_demo-%5Bu9vv19BoRd0%5D.mp4


状态保存和加载,也称为无限恢复,是一种简单的作弊技巧,可以帮助你更轻松地玩游戏。

NES没有X和Y按钮,我们要把它们用作状态保存和加载的按钮。

注意:

Nofrendo 设计了 10 个状态保存和加载插槽,目前 arduino-nofrendo 只能使用第一个插槽(插槽 0)。

步骤22:预制的 ESP32 控制台
目前市面上很少有预先构建为游戏机的ESP32开发设备,例如:

[*]TTGO T-Watch + Game 模块
[*]ODROID-GO
[*]M5Stack + M5Stack CardKB

步骤23:TTGO T-Watch + Game 模块

https://dfrobot.loll.cc/video/arduino-nofrendo%40TTGO_T-watch_with_Game_module-%5B84Oa6U_fY8I%5D.mp4



[*]打开 esp32-nofrendo 示例代码("文件" -> "示例" -> "arduino-nofrendo" -> "esp32-nofrendo")
[*]选择 "TTGO T-Watch"("工具" -> "板子" -> "TTGO T-Watch")按下上传按钮
[*]上传数据("工具" -> "ESP32 Sketch Data Upload")

参考:

https://t-watch-document-en.readthedocs.io/en/latest/introduction/index.html

步骤24:ODROID-GO


[*]打开 esp32-nofrendo 示例代码("文件" -> "示例" -> "arduino-nofrendo" -> "esp32-nofrendo")
[*]选择 "ODROID ESP32"("工具" -> "板子" -> "ODROID ESP32")
[*]按下上传按钮

参考:

https://www.hardkernel.com/shop/odroid-go/


步骤25:M5Stack + M5Stack CardKB

https://dfrobot.loll.cc/video/arduino-nofrendo%40M5Stack_with_CardKB-%5BTMt3Yy51bIw%5D.mp4



[*]
打开 esp32-nofrendo 示例代码("文件" -> "示例" -> "arduino-nofrendo" -> "esp32-nofrendo")
[*]
选择 "M5Stack-Core-ESP32"("工具" -> "板子" -> "M5Stack-Core-ESP32")
[*]
按下上传按钮

注意:

CardKB 一次只能读取一个按键被按下的信息,适合玩某些特定的游戏。

参考:

https://m5stack.com/collections/m5-core

https://m5stack.com/products/cardkb-mini-keyboard

步骤26:开始享受游戏


Arduino IDE 是一个非常易于使用的平台。esp32-nofrendo 示例只是一个起点,你可以在其上添加更多的功能,例如:

[*]触摸屏 UI
[*]像 RetroPie 一样的带艺术图像的游戏选择 UI
[*]玩游戏时进行存档
[*]状态插槽选择
[*]带存档的状态保存
[*]状态浏览和加载 UI,带有存档预览
[*]音量设置
[*]LCD 背光设置

赶快动手做一个你自己的 Arduino NES 吧!

参考资料
最佳自制任天堂娱乐系统游戏: http://www.nesworld.com/article.php?system=nes&data=neshomebrew_bestof

原文作者:陳亮

原文链接:https://www.instructables.com/Arduino-NES/

译文首发于:DF创客社区

转载请注明来源信息

独钓寒江雪 发表于 2023-3-23 18:41:22

esp32+4.0英寸LCD液晶屏+NES,简直无敌

三春牛-创客 发表于 2023-3-28 16:23:15

厉害厉害

三春牛-创客 发表于 2023-3-28 16:25:56

学习了!感谢分享

花生编程 发表于 2023-3-28 16:29:06

厉害厉害

花生编程 发表于 2023-3-28 16:30:08

不错不错

腿毛利小五郎 发表于 2023-4-5 10:15:19

厉害厉害

派大星ym 发表于 2023-8-21 09:44:25

酷酷酷酷酷

派大星ym 发表于 2023-8-21 09:46:30

66666666666

爱好者Ard 发表于 2023-8-23 09:38:36

膜拜,膜拜, 大神
页: [1]
查看完整版本: 超详细教程!自制一个Arduino NES(红白机)游戏机!