用 ESP32、双舵机、SSD1306 OLED 和 MP3 模块,做一只会自己关开关的马里奥问号砖。本文按备料、打印、焊接接线、九步装配、固件烧录和音频导入展开,配合项目原图说明关键操作,再讲清表情素材与音效数量的修改条件。
视频演示
代码开源
硬件开源
有些开关是用来开灯的,有些开关是用来开机的。这个开关比较特殊:拨上去以后,盒子会伸出一根杆,把它拨回来。
你负责打开,它负责关闭。分工明确,合作为零。
这就是无聊盒子 Boring Box。给它套上马里奥问号砖的外壳,熟悉的游戏道具就变成了桌上一只不太配合的盒子。问号仍然挂在外面,里面等着你的却不是金币,而是一场“我偏要关掉”的小动作。

接下来沿着实际制作顺序,把备料、打印、焊接、接线、装配、烧录和素材整理走一遍。先把这只盒子装起来,再考虑给它换台词、换表情,比较容易知道每一步在解决什么问题。
先分清复刻路线,再整理资料
盒子里有两只舵机:一只负责翻盖,另一只带着无聊杆去拨开关。两套机构各管一件事,配合 PCB、OLED 和 MP3 模块,组成这只问号砖。
目前资料包保留了可供烧录的 bootloader.bin、partition-table.bin 和 firmware.bin。装出盒子、烧录现成程序,是现在可以沿着资料操作的路线。 完整的 Boring_box 主固件工程暂未包含在当前仓库中;如果要改舵机动作、显示内容或选曲数量,需要先补齐主工程和构建环境。
资料可以按下面几处查找:
DIY_Boring_Box/
├── 01_UI设计/
│ ├── GIF/ 开机动画、随机动画及逐帧素材
│ ├── 舔狗表情/ PNG 表情素材
│ └── 音效集/ 01—04 文件夹、上传说明和模块手册
├── 02_三维模型/
│ ├── 3D打印/ STEP、拓竹参数参考.3mf、打印清单.xlsx
│ ├── 外购/ 配件参考模型
│ └── *.SLDPRT、*.SLDASM 零件与装配模型
├── 03_采购清单/
│ ├── BOM.xls PCB 元件型号、位号和封装
│ └── 采购清单.xlsx 五金、配件、工具与转换线
├── 04_firmware/
│ └── 模块数据手册/ 模组手册和独立 MP3 模块示例
└── 05_固件烧录/
├── firmware_bin/ 三个现成固件文件
├── flash_download_tool_3.9.6_0.zip
└── 烧录必看.docx
04_firmware 下的模块示例适合配合模块手册学习,不能直接当作整盒主程序编译。打印目录提供的是 STEP 模型和 .3mf 参考工程,需要 STL 时,可从模型软件导出后再切片。

把电子件、五金和转换线备齐
先打开两份采购表:BOM.xls 管 PCB 上的元件,采购清单.xlsx 管外购配件、五金和线材。焊接电路板时按位号与封装核对,购买外壳配件时按下面的规格准备。
电子件与外购配件
| 配件 | 采购资料中的规格 | 制作时要核对的地方 |
|---|---|---|
| 主控 | ESP32-WROOM-32E,4MB Flash;BOM 完整型号为 ESP32-WROOM-32E-N4 | 对照 U1 位号与模组封装 |
| 舵机 | 两只 MG90S 金属齿舵机,采购标称 180° | 舵机尺寸、舵盘与打印件的配合 |
| OLED | 0.96 英寸、4 针、蓝色显示,SSD1306,采购款未焊排针 | 驱动芯片、四针定义及排针焊接 |
| MP3 模块 | 模块及配套 PH2.0 端子线,公对公 | 模块接口与配套连接线 |
| 电池 | 103450 单节锂电池 | 电池尺寸、接头与极性 |
| 纽子开关 | MTS-102,三脚两档 | 开关尺寸与接线端子 |
原教程的配件图以 SG90 舵机作示意,并注明可以使用其他舵机;采购清单列的是两只 MG90S。上面的备料表沿采购清单整理,更换型号时要核对尺寸、舵盘和机构行程。OLED 则要核对 SSD1306 芯片,不能只看“0.96 英寸、四根线”就当作同一种屏幕;换成其他驱动芯片,需要移植相应代码。
五金规格与数量
下面保留采购清单里的数量和用途,尤其要分清平头、沉头以及不同长度:
| 五金件 | 规格 | 数量 | 用途 |
|---|---|---|---|
| 螺母 | M2 | 4 | 固定舵机 |
| 销轴 | φ2 | 2 | 翻盖转轴 |
| 平头螺钉 | M2 × 7 | 4 | 固定舵机 |
| 平头螺钉 | M3 × 10 | 2 | 翻盖转轴杆连接 |
| 沉头螺钉 | M3 × 14 | 4 | 固定底座 |
| 平头螺钉 | M3 × 12 | 7 | 固定电池、PCB |
| 平头螺钉 | M4 × 8 | 2 | 固定 MP3 模块 |
转换线与工具
| 项目 | 采购规格 | 用途 |
|---|---|---|
| OLED 屏幕线 | PH2.0 4P 转杜邦 2.54 单针,20cm,采购规格为 5 条装 | 板载 PH2.0 接口转接 OLED |
| 舵机线 | 3P、1.25mm 公头转舵机母头,清单列两条 | 板载 1.25mm 接口转接两只舵机 |
| 纽子开关线 | 1.25mm 公头、2P、20cm,采购规格为 10 条装 | 板载接口转接到开关焊接端 |
| 迷你棘轮扳手 | 批头款,配 10 个批头、加磁器和收纳袋 | 盒子内部的螺钉装配 |
| 胶枪 | 参考采购规格为 40W,配 15 根胶棒 | OLED 热熔胶固定 |
准备配件时可以对照原教程的这张实拍,理好两只舵机、OLED 屏幕、纽子开关和转换线;MP3 模块与电池另按清单准备。图中的舵机型号以 SG90 作示意,备料仍按上面的采购规格核对。

这里的“5 条装”“10 条装”是购买包装规格,不是每只盒子的用线数量。MP3 模块还要备好采购款随附的端子线;连接电脑烧录则需要能传输数据的 Micro USB 线。
焊接另备烙铁、焊锡、助焊剂和镊子,检查线路可用万用表。五金按型号分开放,接下来拧螺钉时就不用临时测哪一根更长。
打印外壳,先试配再固定
02_三维模型/3D打印 中的 STEP 文件对应下面这些零件:
| 打印件 | 数量 |
|---|---|
| 主体 | 1 |
| 底座 | 1 |
| 盖子 | 1 |
| 电池盖板 | 1 |
| 开盖杆 | 1 |
| 开盖杆 B | 1 |
| 无聊杆 | 1 |
| 键帽 | 16 |
| 问号 | 3 |
| 小问号 | 1 |
先检查模型是否齐全,再打开 拓竹参数参考.3mf 查看参考工程。使用时核对打印机与切片设置是否适合自己的设备,按实际设备调整配置,打印后试配孔位和连接件。
工程中保留了两张打印板预览,先看主要结构件,再看问号和圆点装饰件:


部分结构采用打印出来的内置螺纹,打印精度会影响装配。 螺钉、舵机和连杆正式固定之前,先检查螺纹、孔位、舵机安装空间和盖子转轴。不要一路拧到底,才发现某个孔位不合适。
先把主体、盖子和两套连杆的活动空间确认好,再处理外侧的小件。开盖杆能不能顺畅带动盖子,无聊杆能不能碰到开关,收回时会不会顶住外壳,都比一次把装饰件贴齐更值得先检查。
焊接 PCB,逐一核对配件接口
拿到对应的 PCB 与元件后,先对照 BOM.xls 的型号、位号和封装检查备料。除了 ESP32 模组,表中还列有 CH340X、AMS1117-3.3、TP4056、Micro USB 座,以及电阻、电容和各类连接器。焊接时跟着位号走,具体方向与连线以电路资料为准。
先认清 PCB 两面的接口
先看主控与电源这一面。下表的上、下、左、右都按这张图来读,翻面后方位会改变;实际接线时以接口丝印识别。

| 图中位置 | 标注或部件 | 用途 |
|---|---|---|
| 上方偏右 | Micro USB | 连接电脑充电、烧录 ESP32 固件 |
| 右侧 | 滑动电源开关 | 控制盒子电源 |
| 底部 | POWER |
电池接口 |
| 底部 | SW |
纽子开关接口 |
| 左侧 | MCU 复位按键 | 复位主控 |
| ESP32 模组右侧 | LED 充电指示 | 图中标注的充电指示位置 |
滑动电源开关和纽子开关是两件事。 前者位于 PCB 上,用来控制电源;后者接到 SW,是你拨动后让盒子作出回应的触发开关。
再看外设接口这一面,先按 OELD、PWM1、PWM2、MP3 四处标注找接口:

| 图中位置 | 丝印 | 对应配件 |
|---|---|---|
| 上方 | OELD(原图拼写) |
OLED 显示屏接口 |
| 右侧上方 | PWM1 |
翻盖舵机 |
| 右侧下方 | PWM2 |
无聊杆舵机,也就是负责拨开关的舵机 |
| 底部 | MP3 |
MP3 音频模块 |
两只舵机先按用途区分,再分别接到 PWM1 和 PWM2。插线前还要对照电路资料确认针脚定义、极性和插头方向,接口位置对了,并不代表每根线已经接对。
焊接与配件接线
可以按下面的顺序完成这一阶段:
- 断开电池和 USB,核对元件。 对照 BOM 检查阻值、容值、芯片型号和封装;有方向要求的元件按电路与封装标记安装。
- 完成 PCB 焊接并检查焊点。 检查有无连锡、漏焊和连接器方向错误;需要检查电路时先使用万用表,不直接靠通电碰运气。
- 处理 OLED 排针与开关线。 采购表中的 OLED 未焊排针,先完成四针焊接;纽子开关使用清单中的两芯转接线,实际接到哪两个端子按接线资料核对。
- 逐项连接配件。 OLED 屏幕对应
OELD,翻盖舵机对应PWM1,无聊杆舵机对应PWM2,音频模块对应MP3,纽子开关对应SW,电池对应POWER。核对定义后再插接与装配。
板载接口较多,要把“插头能够插进去”和“电气定义对应”分开检查。四线 OLED 转接线、两条舵机转接线和开关线的用途不同,具体引脚与方向按这块 PCB 的接线资料核对,不靠线色猜接法。独立模块示例中的开发板接线,也需要先核对后再用于自己的电路。
OLED 怎么固定
原装配方案在盒子内部使用热熔胶固定 OLED。先确认屏幕的位置和接线,再固定模块,给线材留出机构活动所需的空间。
如果希望改成开孔固定,需要修改对应的外壳模型,再重新打印。改变固定方式属于模型修改;更换显示芯片则属于驱动修改。 两件事分开处理,避免外壳装好了才发现屏幕无法被原程序驱动。
按原九步装配,把内部位置留出来
盒子主要采用内部固定方式。先看半透明外壳的内部结构渲染,理解电池、舵机、连杆和底座上的模块如何放在一起,再开始装配。


装配时照下面的顺序走,前面的部件会占据后续走线和拧螺钉的空间,顺序别急着省略。
1. 固定电池
先把电池放到对应位置,装好电池固定结构,整理引线。电池与 PCB 共用采购清单中的 M3 × 12 平头螺钉规格,具体分配按装配模型确认。
2. 固定纽子开关
把 MTS-102 安装到对应位置,检查拨杆是否能正常切换。此时先看无聊杆伸出后的接触位置,接线端和引线也要给后面的舵机留出空间。
3. 固定无聊舵机
安装负责拨开关的舵机,再试配舵盘和无聊杆。两只舵机的固定件合计为四个 M2 螺母和四个 M2 × 7 平头螺钉。先确认机构位置,再最终拧紧。
4. 固定翻盖舵机
安装负责翻盖的另一只舵机,试配开盖杆和开盖杆 B。检查连杆与外壳的配合,先保留调整空间,不用拧紧螺钉去强行修正位置。
5. PCB 接线
再次逐项核对配件接口:翻盖舵机接 PWM1,无聊杆舵机接 PWM2,纽子开关接 SW,电池接 POWER,屏幕和音频模块分别接 OELD、MP3。整理线路,避免盖子和无聊杆活动时碰到或拉扯线材。
6. 在底座固定 MP3 模块
按模块模型和底座位置安装 MP3 模块,采购清单对应的是两颗 M4 × 8 平头螺钉。确认模块连接线可以接入,再固定模块。
7. 在底座固定 PCB
安装 PCB,固定规格为 M3 × 12 平头螺钉。电池和 PCB 共计需要七颗这一规格的螺钉,按实际装配位置分配,不把这七颗全算到 PCB 上。
8. 固定底座
检查内部部件固定与走线,再用四颗 M3 × 14 沉头螺钉固定底座。封上之前确认线材没有被压在接合处,需要调整接口时此时更容易处理。
9. 连接翻盖
装好盖子与翻盖机构,翻盖转轴使用两根 φ2 销轴,转轴杆连接采用两颗 M3 × 10 平头螺钉。最后检查盖子的行程,以及无聊杆伸出、收回时的活动空间。
每完成一套机构,就检查一次配合。硬件卡住的时候,多写两个延时,通常只是让它晚一点卡住;先让盖子和杆能够自由活动,再看程序怎么安排动作。
烧录现成固件,把盒子叫醒
资料里的烧录步骤使用 Windows 版 ESP32 Download Tool,附带工具包为 flash_download_tool_3.9.6_0.zip。先解压工具,安装 CH340 串口驱动,连接电脑后确认能识别板子的实际 COM 口。
烧录文件在 05_固件烧录/firmware_bin,三个文件都要选中,并分别填写地址:
| 固件文件 | 烧录地址 |
|---|---|
bootloader.bin |
0x1000 |
partition-table.bin |
0x8000 |
firmware.bin |
0x10000 |
接下来按原烧录截图配置:
- 选择三个文件,勾选三行。
- SPI SPEED 选择 40MHz。
- SPI MODE 选择 DIO。
- 勾选 DoNotChgBin。
- COM 选择当前电脑识别到的端口,BAUD 先使用 115200。截图中的 COM11 是当时的端口编号,不需要照抄。

开始下载前,同时接上电池和 Micro USB。 项目烧录说明明确指出,只接 Micro USB 不会经稳压部分给 MCU 正常供电,所以不要省略电池连接。
按说明使用板载自动下载功能,无需另行手动配置下载控制引脚,点击 START 开始烧录。出现失败时先核对 COM 口、三个文件勾选与地址、双电源连接和 Flash 参数,再降低波特率重试。
三个文件各有自己的位置:启动程序、分区表和应用分别写到对应地址。更换 USB 端口、电脑或线材之后,先重新确认 COM 口,再启动下一次下载。
直连 MP3 模块,把音效复制进去
音频导入和 ESP32 固件烧录是两个操作。项目的音频说明使用 直连 MP3 模块、复制粘贴音频文件 的方式,音频不是通过上面的三个 .bin 文件导入。
随附模块资料展示的是带 Micro USB 接口的音频模块,并说明通过 USB 存储方式更新音频。这里的“直连”指连接 MP3 模块自身的 USB,选购模块时也要核对它是否提供这一接口和导入方式。


操作时可以这样整理:
- 在电脑上打开
01_UI设计/音效集,先备份原有文件。 - 用 MP3 模块自身的 Micro USB 接口连接电脑,按照模块资料进入可复制文件的存储区。
- 日常音效放入
03文件夹;惊喜音效放入02文件夹。 - 替换原音效时,按原有文件名编号整理新文件,再复制粘贴到对应目录。
- 复制完成后核对目录与文件名,再按装配方式连接模块进行试听。
现有 03 日常音效从 001xxx.mp3 编到 082xxx.mp3;02 惊喜音效有 001xxx.mp3 到 007xxx.mp3,还存放着 长112.mp3、长126.mp3 两个未按这套编号命名的文件。目录里有九个文件,不代表程序就会随机选到九个编号。
保持现成 firmware.bin 时,优先保留原有 02、03 目录和编号,用新音频替换对应编号的原文件。试听时留意音频开头的空白、音量与长度,一句简短回应,往往比一大段台词更容易接上开盖、关开关的节奏。
增加音效数量,为什么还要改程序
原音效说明给出了下面这段播放逻辑:

playFileNumber(2, random_count) 调用惊喜音效目录,playFileNumber(3, random_count) 调用日常音效目录。程序里的选曲范围也要和文件编号匹配:
| 音效组 | 说明中的现有范围 | 对应编号 | 扩充示例 |
|---|---|---|---|
02 惊喜音效 |
random(1, 8) |
1—7 | 连续编号扩充到 50 时,改成 random(1, 51) |
03 日常音效 |
random(1, 83) |
1—82 | 连续编号扩充到 100 时,改成 random(1, 101) |
Arduino 的 random(min, max) 不包含上界。例如,编号为 1—50 时,选曲语句写成:
uint8_t random_count = random(1, 51);
这只是修改范围的示例。要让盒子使用新的选曲范围,需要在完整主工程中修改、重新构建,再烧录新程序;只复制更多文件到 MP3 模块,不会自动改变固件里的范围。当前资料中的独立 MP3 示例和模块手册可以帮助理解调用方法,整盒程序的修改仍要等主工程补齐。
惊喜音效的说明截图使用动作计数、取模和变化的间隔,不能简单当作“每隔固定 10—15 次必定播放”。先把文件、目录和编号对齐,再调整策略,会更容易判断问题出在音频还是程序。
OLED 素材先选好,改显示还需要主工程
01_UI设计 不只有音频,也保留了一个开机 GIF、26 个随机表情 GIF、对应的逐帧图片,以及 80 张静态表情 PNG。这些素材可以先在电脑上查看,挑选想用于屏幕的内容。
下面是开机素材的第一帧。它是项目现成的 PNG 帧,先用它检查构图,再对照同目录里的完整 GIF 查看动画。

随机动画也保留了对应的逐帧图片。这里各选一张首帧,原 GIF 与逐帧 PNG 可以对照查看;这些是图像素材预览,实际显示要经过屏幕适配。
| 随机 GIF 2 的第一帧 | 随机 GIF 6 的第一帧 |
|---|---|
![]() |
![]() |
静态表情放在 舔狗表情 目录,可以从中挑选内容。比如下面这四张,就能先组成一套情绪变化的素材:
| 微笑与皱眉 | 爱心眼与睡眠 |
|---|---|
![]() |
![]() |
![]() |
![]() |
第二行分别是皱眉与睡眠表情。它们都是原始素材,接入 OLED 时要按实际屏幕分辨率缩放,进行单色处理,并适配主工程的图像接口。
整理显示素材时,按下面的顺序准备:
- 先看素材。 动画先看完整 GIF,静态表情看原 PNG;挑选内容时留意画面是否适合小尺寸屏幕。
- 再整理帧。 GIF 对应的逐帧目录可用于查看和调整动画顺序,保留自己的素材副本,避免覆盖原文件。
- 确认目标屏幕。 这套项目按 SSD1306 屏幕准备;改用其他驱动芯片,先移植驱动再处理显示内容。
- 在主工程中接入。 图像需要按显示驱动使用的格式接入代码,动画还要配合帧序与播放逻辑,最终重新构建并烧录。
现成 .bin 固件里的显示内容不能通过把 PNG 或 GIF 复制到 MP3 模块来更换。主工程尚未包含在当前仓库时,可以先整理素材、制作自己的动画版本;实际接入与重新烧录,需要等主工程和显示代码齐备后完成。
分阶段检查,比一次装完再猜更省事
可以把检查分成三轮:装配时检查机构与接线,下载时检查驱动与参数,运行时再看开关、动作、显示和声音。某一步出现问题,就回到对应阶段找原因。
| 遇到的情况 | 优先检查 |
|---|---|
| 电脑找不到 COM 口 | CH340 驱动、Micro USB 数据线、连接状态,以及当前电脑识别到的端口 |
| 固件下载失败 | 电池和 USB 是否同时接入,三个文件是否勾选,地址与 40MHz/DIO/DoNotChgBin 参数;再降低波特率 |
| 盖子或无聊杆活动受阻 | 舵机、舵盘、连杆与外壳配合,转轴位置,以及是否有线材挡住机构 |
| OLED 没有正常显示 | 是否为 SSD1306,排针焊接、四针接口对应与连接方向;其他芯片需要驱动移植 |
| 音频没有按预期播放 | MP3 模块接口、02/03 目录、文件编号与现成程序的选曲范围 |
| 新增音频一直没有选到 | 文件编号是否超出了固件中的范围;范围变化需要修改完整主程序并重新烧录 |
把每个阶段先做对,再进入下一个阶段。这只盒子真正的乐趣,是让打印件、电路和程序一起完成一件看得见的小事。
换完音效、调好机构,再拨一下开关:你把它打开,它认真地关掉。问号砖还是那块问号砖,只是这一次,里面装着你亲手做出来的“不配合”。
参考资料
鸿尘客 Honchic · 把脑洞焊到电路板上





