在 ESP32 电子纸上以 30 帧运行 Game Boy
文章摘要
这是 YouTube 频道 Bo Made It 发布的一段 9 分钟视频(10 月 8 日上传)。作者给一块小尺寸的 ESP32-S3 电子纸开发板(微雪 Waveshare ESP32-S3-ePaper-1.54,1.54 英寸、200×200 像素)写了自定义显示驱动,把刷新速度提到每秒约 30 次,还能显示 4 级灰度,足以流畅运行 Game Boy 模拟器。以下内容根据视频简介、章节列表和视频字幕整理。
为什么要这么做。 作者本来在用这块板子做一个个人小设备:背 Anki 卡片、录语音备忘,或许还能当迷你阅读器。但他发现菜单切换慢得令人痛苦。用板子自带的驱动跑 Game Boy 模拟器,理论上每秒 3 帧,实际只有 2 帧,就是幻灯片。微雪标称局部刷新约需 300 毫秒。他原以为电子纸本来就慢,但他之前看过别人做的 PaperBoy 项目(一个跑在电子纸上的 Game Boy 模拟器,视频简介里附了它的视频链接),知道电子纸可以很快。问题是 PaperBoy 用的面板直接暴露行列接口,而他这块板子上有专用的显示控制器在驱动面板,绕不过去,没法直接移植 PaperBoy 的驱动,只能针对这个控制器重写。
电子纸为什么慢。 和 LCD、OLED 不同,电子纸靠带电的黑白颜料颗粒在物理上”存住”图像:改变电场,颜料就被推向或拉离表面,像素看起来就是黑或白。为了干净地切换到新图像、不留下旧图的残影,驱动通常要发一串多步的电脉冲(称为波形,waveform),先把颜料来回摆动几次,再推到目标状态,这个过程很耗时。
第一步:缩短波形。 他逐步删减标准波形,看删到什么程度图像开始变差,结果发现能删掉很多:从约 17 个驱动步骤减到 2 个,加上前后处理,一次完整更新大约 50 毫秒,接近每秒 20 次。代价是画面很糟:残影非常明显,因为每个像素过渡的时间不够;长时间运行后整个屏幕还会慢慢变灰。
第二步:逐像素驱动。 他回到 PaperBoy 的思路:不再每次都驱动整块面板,而是为每个像素维护状态,只驱动真正需要变化的像素。像素一变化就分配一个”驱动预算”,每给它一个脉冲预算就减一,够了就停。这让静止区域干净得多,残影大幅减少。他发现 6 到 8 次驱动足以完成一次完整的黑到白转换。这里也有取舍:驱动越多,最终像素越清晰,但运动物体过渡时间越长、看起来越糊。随后他继续压缩周边开销,经过几轮长时间的来回调试,扫描已经能每 33 毫秒左右开始一次,实际游戏效果出乎意料地好。
第三步:真正的 4 级灰度。 Game Boy 有 4 级灰度,此前他用抖动(dithering)拿黑白像素去模拟。PaperBoy 也这么做,但它的面板分辨率高得多,一个 Game Boy 像素(原画面 160×144)可以对应好几个物理像素;他的屏只有 200×200,一个 Game Boy 像素只对应一个物理像素,抖动纹理非常明显。在对付残影时他注意到,屏幕其实已经在”意外地”产生灰色,因为颜料不会瞬间从黑跳到白。那么如果故意在过渡中途停下,能不能按需产生灰阶?答案是可以。静态灰度图相对容易,难的是画面不停变化时灰度仍然稳定:4 种灰度之间有 12 种转换,每种需要的驱动预算都不同。他为每种转换编写测试,比如让一块某种灰度的色块在另一种灰度的背景上移动,看色块是否到达目标灰度、移开后背景能否恢复。因为控制器”看不见”颜料的实际状态,他搭了一套装置在板子上跑转换测试并拍照录像,人工检查、调整参数,一遍又一遍地重复。经过”非常非常多”的校准,终于得到不用抖动的真 4 级灰度输出,虽然仍不完美。
声音和手柄。 这一部分反而比 PaperBoy 简单:PaperBoy 所用的 Paper S3 只有蜂鸣器,而这块板子有专门的音频编解码芯片和扬声器,可以直接播放模拟器的声音,效果不错。他还改了一个 NES 手柄的设计,用 ESP32-C3 加按键和 3D 打印外壳做成 USB 手柄,理论上也支持其他蓝牙手柄。
现状与后续。 驱动还没完成,复杂场景下帧率会略低于 30,一些灰度转换还需要更好地校准。视频简介里已经给出了驱动加模拟器(GitHub 上的 kuslota/InkBoy)以及手柄代码和打印文件的仓库链接,并声明”按原样提供,自定义波形风险自负”。作者还坦白:自己是软件工程师,玩微控制器几年了,但显示驱动不是他的专长,很多代码是 vibe coding 写的,即便如此也花了大约一个月的深夜时间。他特别感谢 PaperBoy,称其为灵感来源和逐像素驱动方法的基础。最初那个项目的菜单现在也快得出奇,他正在为这块板子做一个类似迷你操作系统的东西,包括在线 Anki 计划、接入 Obsidian 的语音备忘,可能还有本地语音转文字。
HN 评论精华
帖子 150 分、四十多条评论。大家一边惊叹,一边追问一个核心问题:既然这么简单就能快这么多,厂商为什么不做?
为什么厂商没这么做。 Lerc 说,视频里提速用的几乎都是他以为电子纸早就在用的招数,他一直以为现在的慢已经是试遍各种技巧后的极限,”这让我怀疑,还有多少东西只要有个在乎的人认真对待,就能好得多”。jdiff 和 anonymous_user9 猜原因可能是寿命,驱动得越狠,屏幕坏得越快。gsliepen 反驳说这里其实是驱动得更少,主要风险在于灰阶定义不稳:同样的脉冲序列得到的灰度可能随面板老化、温度等环境因素漂移;他还听说处在灰阶时黑白颗粒混在一起,可能互相交换电荷,导致部分颗粒以后不再正常移动,但他不确定这在物理上是否成立。aix1 问是不是每块屏都要单独校准,温度过高过低会不会失准;RossBencina 说标准驱动会考虑温度,aix1 补充说,只官方支持黑白的屏,驱动只需知道工作温度范围内最慢的转换时间,统一用它就行,灰阶就复杂多了。gblargg 设想能否监测线路电流来判断像素是否完成转换,从而形成反馈闭环。RossBencina 还好奇灰阶校准能不能完全自动化,不用人来看。
高速电子纸还有意义吗。 somat 问电子纸的意义不就是断电后画面仍然保持的静态显示吗,高速驱动还有什么优势?ThrowawayR2 说他在开了快速刷新的电子书阅读器上浏览网页,耗电和普通平板一样快,30 帧只会更糟。其他人给出理由:kogens 说阳光直射下可读性好,不需要很强的背光;RossBencina 说背光屏会诱发他的偏头痛,高速电子纸几乎是他使用传统交互界面的前提,约 15 帧打字还行,鼠标指针就很难受,反射式 LCD 也是一个选项。versluis 和 gblargg 指出作者的本意就是让一个大部分时间静态的设备响应更快,模拟器只是演示,”动画从每秒一两帧提升到更高,手感差别很大”。
电子纸到底指什么。 y1n0 认为视频把电子纸等同于颗粒式显示有误导性:E Ink 是电泳显示公司的商标,”电子纸”只是个谁都能用的非正式类别,有些基于 LCD 的屏也叫电子纸。cubefox 回应说,实际上绝大多数电子纸就是电泳屏,大多出自 E Ink;15 到 20 年前很多公司尝试过别的反射式技术,有的支持彩色或高速响应,但都关门了,如今另一种主要类型是简单的反射式灰度 LCD,响应快但不具备双稳态,白色发灰。mdp2021 则坚持这个词很滑,连网络新闻产品都自称”epaper”。
Game Boy 原装屏的往事。 novia 问原版 Game Boy 的 STN LCD 有什么局限。cubefox 说初代 Game Boy 和 Game Boy Pocket 的像素响应很慢,残影严重,可能和视频里的效果差不多;LCD 天生是透射式的,做成反射式时环境光要两次穿过液晶和偏振片,吸收很多光,所以反射式 LCD 总是偏灰。NBJack 回忆有些游戏专门利用了慢响应:《银河战士 II》暂停时整屏会缓慢、轻微地脉动,其实是像素在快速闪烁,被老 LCD 的慢过渡平滑成了亮度变化;cubefox 补充说日本射击游戏《地球解放军 ZAS》也借此实现了半透明背景层。weltensturm 提到如今 Pebble 手表和 Daylight Computer 用的是半透反射式 LCD。
其他。 hobo123 说现在想让 Kindle 用上这个驱动再跑原生 Android,thepryz 回应说 Boox 等安卓墨水屏平板早就有高刷模式。hiisukun 在用一款 ESP32 驱动的小墨水屏阅读器 X3,期待这类驱动改进早日普及到别的设备。karim79 推荐了朋友 Larry(bitbank2)的 GitHub,里面有大量电子纸极限优化的工作。