Skip to content

2026-08-14 Paperboard:联网七色电子纸信息板,从设备自己画图到多云生成整张画面

  • 项目形态:800×480 七色电子纸信息板
  • 显示硬件:Good Display GDEY073D46 + 裸 DESPI-C73
  • 计算平台:ESP32、ESP8266、1 MiB ESP8285
  • 固件主线:ESP32 render-only 0.7.2;ESP8266/ESP8285 RTOS SDK render-only 0.2.0
  • 云端主线:Cloudflare Workers + Durable Objects 状态参考实现;Tencent EdgeOne Cloud Functions Node/Sharp 组合入口
  • 机械主线:GPT 参与设计的 RhinoCommon 参数化外壳与零五金 3D 打印桌面支架

我们实现了一台什么设备

我们把实时资讯、市场行情、天气、家庭温度和照片放到一块 7.3 英寸七色 ACeP 电子纸上。Paperboard 无需浏览器或手机常驻,接通电源后自行联网、取帧、校验、缓存并驱动屏幕;电子纸断电后仍保留最后画面。

当前系统已经形成完整的软硬件闭环:

能力已实现的形态
信息布局layout1 展示未来 12 小时温度、降水与 UV、AQI、预警、天气详情、五条快讯、五个市场和两个房间温度;layout2 展示 500×416 动态图片与紧凑信息栏
照片模式photo 使用 800×480 fit-cover 全屏图片,不叠加标题、时间或署名
七色图形天气场景、图标、文字和照片统一量化到 GDEY073D46 的黑、白、红、黄、蓝、绿、橙七色
本地交互Boot 短按立即刷新,长按在 layout1 → layout2 → photo 之间循环;每种布局独立设置刷新周期和安静时段,成功手动刷新后重新对齐周期
多平台固件ESP32、ESP8266 和 ESP8285 共用帧协议、双槽缓存、调度、配置与 C73 输出逻辑
多云兼容布局、上游模型、字体、量化与 PBF1 由共享核心实现,Cloudflare 与 EdgeOne 只组合各自的 HTTP、图片处理和状态能力
可恢复显示网络或上游异常时重放同布局最后有效帧,并在左下角叠加紧凑本地错误条;相同错误不重复全刷
结构件前框、整体背板与无胶落座底座组成零五金开放式支架,保护裸玻璃、FPC 与背面电子区

一次完整电子纸刷新约需三十秒,因此 Paperboard 的设计围绕“完整帧”展开。画面在进入 C73 之前必须完成长度、色号和双 CRC 校验;传输失败时不发送全刷命令,屏幕继续保留上一张完整内容。

这一版更新了什么

8 月 7 日以来,Paperboard 的主线从“Cloudflare 上的一套全帧 Worker + 两类薄固件”继续收敛为可跨云组合的渲染核心和三平台帧终端。最近一版集中完成了四件事:

  • layout1 把天气区改成行动面板:第一张图显示未来 12 小时分段温度曲线,第二张图在雨天叠加累计降水柱与 UV 曲线,无雨时单独显示 UV;AQI、体感、湿度、风、日出日落和当前预警进入同一固定区域。
  • 温度曲线按蓝、绿、橙、红绝对温区分段;连续高温全部超过 29℃ 时,只在橙/红色域内区分本轮局部高低。UV 使用固定等级色,不随当日最大值漂移。
  • 地区名称、LocationID 和经纬度改由设备配置并随请求发送。新设备或不兼容旧 schema 会显示纯 ASCII 配置页,再通过无回显 UART 事务和 paperboard_config.py 一次写入八个字段。
  • ESP8266/ESP8285 从 Arduino/PlatformIO 迁到 ESP8266 RTOS SDK v3.4;ESP32 0.7.2 默认开启 C73 输出,自动周期、安静时段、Light-sleep 与 Boot 手动刷新都进入共享策略层。

云端同时增加 EdgeOne Node/Sharp 组合入口。共享核心仍只生成标准 Request/Response 和 PBF1,平台 adapter 负责图片变换、状态和部署格式。这样可以在不改固件、不复制布局的前提下选择云端,但“可以构建”与“已经完成线上三布局和实屏验收”仍是两个状态。

最新 PBF1 实帧与三种布局

下面的 layout1 使用代码基线 bf231b7 先生成 144,000 字节 INDEX3 payload,再封装为 144,048 字节 PBF1。报告生成器随后调用 parseFrame() 校验布局、尺寸、header CRC32 与 payload CRC32,最后逐像素解码为网页图。网页图完整来自校验后的 PBF payload。展示城市固定为北京,资讯、房间温度和数值均使用不含个人位置与账户信息的固定 fixture。

Paperboard Layout 1 最新 PBF1 解码渲染
layout1 最新 PBF1 实帧:800×480、144,048 字节,header CRC32 b8853d06,payload CRC32 178ddaa2。左侧是温度、累计降雨/UV、AQI 和天气详情,右侧保留五条快讯与五个市场。

layout2photo 继续使用同一套七色画布、图片量化和帧合同:

Paperboard Layout 2 北京图文信息板渲染
layout2:500×416 七色风景作为视觉主体,行情、天气与快讯压缩进顶部和右栏。
Paperboard Photo 全屏七色风景渲染
photo:同一图片链扩展为 800×480 全屏画面,不叠加城市、标题、时间或状态文字。

三种模式共用一套设备代码。Worker 在同一七色画布上切换排版,输出相同 PBF1 合同;ESP32 与 ESP8285 只按帧头中的布局编号完成缓存隔离和送屏。

技术路径总览

我们在第一阶段把产品完整做进 ESP32,解决电子纸排版、状态合并和真实送屏;第二阶段先迁移图片,再把整张页面迁到 Worker;最终将设备收敛为低内存、可恢复的帧终端。渲染位置改变后,七色像素、PBF1、双 CRC、缓存提交顺序和 C73 输出保持为稳定合同。

第一代:设备自己采集数据、排版并驱动屏幕(core)

数据、排版和显示都在设备上完成

我们先让 core 方案运行在初代双核 ESP32 上:

text
Wi-Fi / SNTP
  -> Jin10 + Lighter + QWeather + 本地传感器
  -> dashboard_collect
  -> dashboard_model
  -> dashboard_runtime
  -> dashboard_core 扫描线排版
  -> C73 SPI adapter
  -> GDEY073D46

dashboard_runtime 管理采集周期、模式、刷新节奏、快照与健康状态,dashboard_core 接收纯模型并输出顺序色号行。渲染器不依赖 ESP-IDF、网络、NVS 或屏幕驱动,同一入口可以连接主机 PPM 预览、dry-run 摘要和真实 SPI sink。

层次主要模块实现内容
数据采集dashboard_collectdashboard_jin10dashboard_lighterdashboard_weathersensor_hub读取真实上游和传感器,维护各自最后有效状态
模型与调度dashboard_runtimedashboard_controldashboard_storage合并模型、持久化配置、控制刷新间隔与模式切换
排版与字体dashboard_coredashboard_font中文换行、行情卡片、天气区、环境页、照片页和诊断图
图片协同worker/dashboard_picture云端获取、裁切与量化图片,端侧以双槽 PBF1 缓存提供像素视图
屏幕输出epd_7in3f_dashboardepd_7in3f将七色色号转换为 C73 4bpp 行,执行初始化、全刷、BUSY 等待与休眠

扫描线渲染绕开全帧内存

800×480 RGB888 画布约需 1.1 MiB,4bpp 全帧也需约 192 KiB。无 PSRAM 的经典 ESP32 无法长期为它们预留连续内存。core 每次只生成一行 800 个七色色号,sink 随即打包成 C73 所需的 400 字节 4bpp 行,页面复杂度不会转化为全帧 RAM 占用。

这个架构还带来一个实用能力:桌面预览与实物固件执行相同布局代码。字体裁片、换行、颜色顺序和图片覆盖位置都可以在主机端复现,屏幕适配器只处理字节打包与时序。

第一代方案确定了产品应该怎样工作

五条快讯作为完整候选提交,天气在整组字段合法后更新,单个行情失败时保留旧值,图片先写非活动槽再切换元数据。数据采集频率与电子纸全刷频率分开,内容没有变化时不驱动屏幕。

这些行为随后迁入 render-only:最后有效帧、双槽原子提交、失败不刷新半帧、相同错误去重,以及把“逻辑刷新”与“传输重试”分开。

为什么把画面生成搬到云端

端侧自治适合快速建立完整产品,却让每次视觉变化都进入固件:TLS、JSON schema、中文字体、天气插画、图片供应商和布局共同消耗 Flash、堆与维护时间。多字号字体和更复杂的图片策略继续增长后,1 MiB ESP8285 无法复用这套组件图。

因此,我们把变化快、计算重的内容层迁到边缘端,让 MCU 的资源集中用于 Wi-Fi、TLS 流读取、Flash 原子性与电子纸时序。

这次迁移还让我们解决了三个架构问题。第一,页面发布与固件发布解耦:修改字体、天气插画或快讯排版只部署 Worker。第二,不同 MCU 看到同一份最终像素,ESP32 与 ESP8285 无需分别实现业务页面。第三,失败边界从多个上游 JSON 收敛为一个固定长度帧,设备只判断 HTTP、PBF1、CRC、Flash 和 C73 五层状态。

架构问题core 的处理方式render-only 的处理方式
页面变化布局、字体、图标和数据 adapter 随固件编译Worker 独立更新完整页面
资源峰值TLS、JSON、字体、图片视图和排版共用 MCU 资源MCU 只保留 TLS 流、行缓冲和 Flash 槽
多平台复用业务组件依赖 ESP32 能力与 Flash 空间ESP32/ESP8285 消费同一 PBF1
上游失败设备分别理解资讯、天气、行情和图片状态Worker 形成完整帧或安全错误,设备保留最后有效帧
视觉一致性各平台需要复现排版实现所有平台显示 Worker 生成的相同像素

我们保留 core 作为参考路线:它用最短路径验证了产品模型、七色排版和 C73 真实约束,并产出可复用的参考渲染器。render-only 建立在这些结果上,把已经稳定的设备语义与持续变化的内容实现分开。

第二代:共享渲染核心在不同云生成完整画面

createWorker() 固定应用入口

公网只暴露鉴权的 POST /v1/render。布局、字体、资讯与天气模型、图片目录、量化和 PBF1 编码都进入共享 createWorker();平台组合根只提供 HTTP 入口、图片变换、量化实现和状态存储。新增云端时不复制 layout1/layout2/photo,设备也不感知后端运行在 Cloudflare 还是 EdgeOne。

Worker 层实现
HTTP 合同Bearer 鉴权、最大 4 KiB JSON、布局、地区名称/LocationID/经纬度校验和 32 位小写十六进制 request_id
数据适配Jin10 快讯、Lighter 行情、QWeather、客厅美居温度、主卧只读快照、Wallhaven/Pixabay 图片目录
共享应用请求规范化、并发采集、三种布局、图片选择、故障分类和安全响应 Header
页面渲染800×480 七色画布、三种布局、预栅格 Noto Sans CJK SC 16/20/24 px 字体
平台能力Cloudflare Images + Rust/Wasm;EdgeOne Sharp + 精确 JS Atkinson;平台状态能力分别注入
帧封装INDEX3 行打包、PBF1 头、header CRC32、payload CRC32 与响应元数据

一次请求内部发生什么

信息布局请求提交地区名称、LocationID、经纬度、布局、网络快照与 request_idphoto 不需要地区字段。Worker 先规范化请求并计算不含地区明文的 SHA-256 指纹。Cloudflare 同 ID、同合同返回持久缓存帧,同 ID 携带不同合同返回 409;共享核心的 inFlight Map 还会把同一实例内的并发重试合并为一次渲染。

layout1 并发启动信息模型、客厅美居温度和主卧只读快照;layout2 再并发图片链;photo 只执行图片链。等待时间由最慢的独立链路决定,不把资讯、天气、行情、家庭温度和图片阶段串行相加。

信息模型要求五条快讯和五个市场完整可用,天气候选按布局一次取得所需字段。两个房间温度是可选字段:客厅 adapter 维护美居登录会话,主卧通过同账户服务的只读 binding 获取快照;任一来源失败时对应位置显示 -- 和状态标记,不阻断其余信息板。设备不上传室内传感器值。

多云兼容的边界

维度Cloudflare Workers + Durable ObjectsEdgeOne Cloud Functions
HTTP 入口Worker fetch,Router 转入固定 Render DONode.js onRequest(context) handler
图片变换Cloudflare Images binding 执行 fit: cover同次函数调用读取原图,npm sharp 完成方向校正、裁切、白底合成与 PNG 输出
七色量化Rust/Wasm 精确 Atkinson共享 JS 精确 Atkinson;Node 20 bundle 把不支持的 Uint8Array.fromBase64() 局部改为 Buffer.from()
状态语义DO SQLite 串行保存完整帧幂等、图片缓存、游标、最近 ID 和美居会话当前只保留单实例并发去重,没有 DO 等价的跨实例持久状态
主卧温度只读 Service Binding尚无等价 HTTPS adapter,保持缺失显示
当前证据生产配置与真实供应商链路已有历史验证Node/Sharp 入口可构建并通过本地合同测试;新 Cloud Function 尚未完成大陆/全球三布局线上验收

Cloudflare 继续承担完整状态语义的参考实现。EdgeOne 提供 Node.js 运行时、Sharp 原生图片处理和可选大陆区域,当前状态一致性限定为单实例范围。bundle 只生成一个 /v1/render Node 函数,函数入口代码约 1.92 MB;包含 Sharp 的 Makers 最终包、冷/热时延、内存、GB-s、上游出站和成都设备链路仍要在线测量。AWS Lambda 当前只记录 event、Sharp 与 DynamoDB/S3 的组合 seam,尚无实现代码。

字体、天气行动面板与七色画布

Worker 的 renderer 直接维护 800×480 色号画布。Layout 1 左栏现在使用白底行动面板:温度曲线按绝对温区切分颜色;第二张图根据降雨状态显示累计降水柱与 UV,或单独显示 UV;AQI、体感、湿度、风、日出日落和预警压进下方固定卡片。Layout 2 把 500×416 图片放在左侧,快讯、天气、行情、两个房间温度和网络状态压缩到顶部与右栏;photo 使用整张图片画布。

中文字体在构建期从固定 Noto Sans CJK SC Medium 生成 16/20/24 px 的 1-bit 字形资产。Worker 运行时不读取 OTF,也不依赖文件系统;测量、换行、截断和字号选择都在 font.mjs 中完成。布局与字体可以随 Worker 发布更新,设备端保持同一帧播放器。

图片选择与跨云量化

Wallhaven 是主图片目录,Pixabay 处理快速失败或候选耗尽。photo 偏向 16:10,layout2 的 visual 变体偏向 4:3;候选需要满足最小尺寸、HTTPS 原图和裁切损失限制。DO 记录当前页与 offset,过滤最近 32 个图片 ID,当前页耗尽后继续下一页。

Cloudflare 组合把原图交给 Images binding 裁切和 PNG 解码,再用 Rust/Wasm Atkinson 输出 3bpp INDEX3。EdgeOne 组合在 Node 函数内用 Sharp 完成同样的 fit: cover 几何,再调用与 Wasm 基线逐字节对照的 JS Atkinson。构建期查找表吸收颜色空间换算,两条路径都不把平台差异带进最终 PBF1。

缓存与降级仍然返回完整画面

在 Cloudflare 参考实现中,完整帧缓存只服务 request_id 幂等,图片缓存只服务图像复用,两者的 TTL 与淘汰队列分开。图片上游短暂不可用时,Render DO 可以选择同变体的有效量化缓存;layout2 没有图片缓存时将图片区留白,信息区仍能组成完整页面。EdgeOne 当前没有跨实例持久图片缓存,图片缓存降级只属于 Cloudflare 参考实现。

所有成功路径最终调用 renderFramePayload() 生成 144,000 字节 payload,再由 encodeFrame() 写入 PBF1 头与双 CRC。响应携带 layout、frame CRC、图片 ID、图片供应商和降级状态等安全元数据,设备无需理解任何上游 JSON。

ACeP 七色量化的多轮迭代

ACeP 面板的像素只有七种物理颜料。普通 RGB 最近色、面向发光屏的调色板和通用照片抖动都无法直接给出稳定观感。我们的图片链经历了四次算法收敛,每次都保留可对照实现。

量化阶段算法解决的问题与结果
端侧参考路径逐行 Bayer 有序抖动只需约 2 KiB 工作集,适合 PPM 诊断;规则纹理明显,照片层次有限
面板感知 v1GDEY073D46 物理 L*a*b* 色心 + 浮点 Lab Floyd–Steinberg从逻辑 RGB 色板转向真实颜料中心,天空高光得到保留;山体和阴影容易混灰
快速试验分支无状态蓝噪声查表去掉误差缓冲并提升速度;实图出现更明显的噪点、色块和层次损失,随后删除
面板感知 v2高光自适应 OKLab + 蛇形定点 Atkinson + 32³ LUT同时保住高光、暗部轮廓与局部对比,成为正式图片量化路径
边缘执行版与 JS 基线逐字节一致的 Rust/Wasm把相同算法放入 Render DO 热路径,支持 RGB888 与 PNG8 快速入口并直接打包 3bpp

同一张图上的量化差异

Paperboard ACeP 量化算法四阶段效果对比
从左到右:原始 RGB 图、物理 Lab Floyd–Steinberg、OKLab Atkinson、当前高光自适应 Atkinson;后三列使用 GDEY073D46 物理色心近似显示。

原图的连续天空、倒影和山体渐变最终只能由七种颜料密度表达。第二列的 Lab Floyd–Steinberg 已经摆脱逻辑 RGB 最近色,天空与山体轮廓完整,但全局误差扩散让中暗部混入较多中性色点。第三列的 OKLab Atkinson 以更小工作集建立更清晰的局部边界,白场比例提高,天空容易趋于平。最右侧加入高光自适应映射后,亮部继续使用白色作为主色,同时让天空、雪线和山脊重新获得蓝、橙与黑色的局部对比;水面倒影也保留了可辨认的层次。

算法差异在网页缩略图上首先表现为色块比例,在 7.3 英寸反射式面板上还会表现为观看距离下的颗粒融合。我们在当前版本中优先保证远看构图、亮暗关系和主体边缘,再利用七色点阵补充局部色感,没有把模拟 LCD 的连续色设为目标。

从逻辑色板转向物理色心

早期 Bayer 路径把七个逻辑 RGB 值当作显示目标,适合验证数据流和色号顺序。真实 GDEY073D46 的红、黄、蓝、绿、橙、黑、白在反射式介质上的亮度与色度中心并不等于屏幕 RGB 参考色。第二版开始使用规格书在 24°C、45°/0° 条件下给出的七个 L*a*b* 中心,颜色选择由“代码里的 RGB 距离”转为“目标颜料的感知距离”。

Lab Floyd–Steinberg 会把误差分配给四个后续像素,连续天空的高光层次得到改善;同样的全局扩散也容易让暗色山体混入过多中性颜料。无状态蓝噪声查表曾用于降低计算量,但实图中噪点和色块更加可见,速度优势没有抵消观感损失。

高光自适应 OKLab Atkinson

当前算法把 sRGB→OKLab、物理色心匹配和高光映射离线写入 32 × 32 × 32 的 5-bit RGB 查找表。输入的每个通道取高 5 位即可得到目标映射:

  • L* <= 65 的山体和阴影保留原输入,让误差扩散继续表达轮廓与暗部差异;
  • L* >= 85 的天空、云层和水面映射到面板黑白点 17.6…70.6
  • 中间区间使用 smoothstep 平滑过渡,避免高光压缩形成硬边;
  • 低色度像素只在黑白颜料中选择,减少灰阶区域的彩色伪影;
  • 七个设备原色所在 LUT 单元固定回对应色号,纯色图标不会被邻近色吞掉。

蛇形 Atkinson 每行反向扫描,把量化误差的 6/8 分给六个未来像素,只需要三行 Int16 误差缓冲。八个像素直接打包为三个字节,不创建完整索引画布。500×416 日间风景的同机量化中位从 34.45–41.60 ms 降到 5.49–5.90 ms,约快 6.1–7.2 倍;速度来自 LUT、定点误差和边量化边打包的组合。

从 JavaScript 基线到 Rust/Wasm 热循环

全帧 Worker 继续沿用高光自适应 Atkinson 的像素语义。JS 版本既是清晰的参考实现,也是 EdgeOne Node 组合的执行路径;Cloudflare Render DO 注入 Rust/Wasm 版本。两者对同一输入逐字节一致。Wasm 内部预分配输入、误差行、调色板和输出存储,避免每次请求重建大对象。

RGB888 入口用于一般解码结果;PNG8 快速入口先对源调色板的每个颜色计算一次 5-bit key 与高光映射,再让像素索引复用该结果。量化器直接写 3bpp payload,PBF 封装可以复用同一 Wasm 线性内存视图。算法升级因此没有改变设备合同,ESP32 和 ESP8285 始终只接收七色色号与双 CRC。

设备只负责下载、校验和显示画面(render-only)

PBF1 固定了云端与设备的边界

字段显示合同
分辨率800×480
像素编码INDEX3,七种合法色号
每行数据300 字节
payload144,000 字节
header48 字节
完整响应144,048 字节
布局layout1layout2photo
完整性header CRC32 + payload CRC32

Worker 与三种 MCU 只通过这份合同耦合。设备不包含 Jin10、Lighter、QWeather、Midea、图片供应商、中文字体或页面布局。新增天气插画、调整字号或更换图片目录时,只更新 Worker。

144 KiB 帧不进入 RAM

HTTP 响应先进入 48 字节头缓冲,再以每行 300 字节流过共享接收器。每行同时走两条路径:一条写入非活动 Flash 槽,另一条把 INDEX3 转成 C73 所需的 400 字节 4bpp 行并送入屏幕 RAM。

接收中断、非法色号、长度错误、CRC 错误或 Flash 回读失败都会停止提交,C73 不收到 0x12。ESP32 使用两个 256 KiB 槽;1 MiB ESP8266/ESP8285 使用两个 144 KiB raw Flash 槽,并关闭 OTA 与文件系统,把空间留给应用、配置和两张完整画面。

三个平台共用行为,adapter 处理差异

共享 C 模块实现 PBF1、CRC、双槽元数据、重试状态机、配置事务、Boot 动作、错误提示和 C73 行协议。ESP-IDF adapter 提供 ESP32 的 NVS、HTTPS 和分区访问;ESP8266 RTOS SDK v3.4 adapter 提供 ESP8266/ESP8285 的 HTTP/TLS、NVS、分区和固定 HSPI。

低资源设备先通过 SNTP 建立 TLS 时间,使用 2,048 字节 HTTP 接收缓冲持续喂给 48 字节头和 300 字节行接收器。TLS 只保留客户端所需的 TLS 1.2、ECDHE-ECDSA、AES-GCM 与 P-256/P-384;设备只持有一条网络流、两条行缓冲和两个可恢复槽,无需构造完整页面对象。

Boot 短按生成新的逻辑刷新,长按把动作投递给主任务完成布局循环与持久化。成功手动刷新后,从 C73 完成时刻重新对齐当前布局的自动周期;失败保留原周期。中断/按键回调只传递事件,不执行 NVS 或网络操作,避免小回调栈承担阻塞任务。

ESP32 与 1 MiB ESP8266/ESP8285 两条设备路线

ESP32:从完整产品到参考实现

ESP32 是 Paperboard 的第一条路线。双核、4 MiB Flash、ESP-IDF、NVS 与 512 KiB image_cache 让它能够承载 core 的数据源、模型、字体、双布局、图片双槽和真实 C73 驱动。产品语义、面板时序和主机/实屏同源渲染都在这条路线上形成。

切换到 render-only 后,ESP32 不再编译业务采集和 dashboard_core0.7.2 固件保留 STA、IPv4、SNTP、客户端 TLS、NVS、两个 256 KiB 完整帧槽和默认开启的 C73 adapter;SoftAP、DHCP server、mDNS、IPv6、企业 Wi-Fi、TLS server/self-test 等未使用能力从专用资源 profile 中裁掉。当前 C73 镜像为 901,648 字节,静态 DRAM 36,936 字节,IRAM 69,963 字节。该版本已经刷入目标 ESP32,串口确认保留配置联网与 C73 默认输出;一次网络失败走完本地错误画面全刷,干净在线 PBF、三布局和长期运行仍需继续实屏复验。

配置 schema v4 由设备持有 SSID、密码、Worker Token/endpoint、地区名称、LocationID 和经纬度。没有完整配置时,设备不联网,直接从固件本地生成纯 ASCII 设置页;paperboard_config.py 可以调用 QWeather 搜索,或使用 macOS Core Location 取得坐标后匹配地区,再通过无回显 UART 事务提交。位置与秘密不进入日志。

ESP8266/ESP8285:用 1 MiB 反推最小系统

ESP8266/ESP8285 把约束压到 1 MiB Flash。它无法复制 core 的 JSON、字体和页面合成,却可以运行 render-only:Bearer HTTPS 返回的 144,048 字节帧不进入 RAM,只流过 48 字节头、300 字节 INDEX3 行、2,048 字节 HTTP 缓冲和 400 字节 C73 行。

这条路线已从 Arduino/PlatformIO 迁到 Espressif ESP8266 RTOS SDK v3.4。ESP8266 与 ESP8285 共用一份 1 MiB DOUT 镜像,不启用 OTA、LittleFS、SPIFFS 或 EEPROM;配置进入普通 NVS,PBF1 进入自定义 frame_cache 分区。

1 MiB 区域地址大小用途
bootloader0x00000SDK 生成启动代码
partition table0x080004 KiB1 MiB 固定分区表
NVS0x09000..0x0EFFF24 KiBschema v4 配置与 CRC
PHY init0x0F000..0x0FFFF4 KiB射频初始化数据
factory app0x10000..0xB0FFF644 KiB单应用 0.2.0 镜像,无 OTA
frame A0xB1000..0xD4FFF144 KiB第一张完整 PBF1 槽
frame B0xD5000..0xF8FFF144 KiB第二张完整 PBF1 槽
SDK 保留尾部0xF9000..0xFFFFF28 KiBSDK 系统保留区域

当前 0.2.0 应用为 557,488 字节,占 659,456 字节 factory 槽的 84.54%,余量 101,968 字节;静态 DRAM 12,148 字节,IRAM 27,404 字节。HSPI 使用 GPIO14 SCK、GPIO13 MOSI、GPIO16 CS、GPIO4 D/C、GPIO5 RESET 与 GPIO12 BUSY。构建和分区已经验证,目标板 TLS、峰值堆栈、C73、掉电恢复与 24 小时运行仍要分别验收。

两条路线共享什么

层次ESP32 路线1 MiB ESP8266/ESP8285 路线共享合同
SDKESP-IDF 6.0.2ESP8266 RTOS SDK v3.4共享业务组件,各自平台 adapter
版本0.7.20.2.0独立版本线,共享协议与控制语义
配置NVS namespace普通 NVSschema v4 事务提交,秘密临时缓冲清零
帧缓存2 × 256 KiB 分区槽2 × 144 KiB 分区槽非活动槽写入、完整回读、元数据后提交
网络esp_http_client + mbedTLSRTOS SDK HTTP client + mbedTLSSNTP、Bearer、固定 /v1/render、流式接收
屏幕ESP-IDF GPIO/SPI adapterESP8266 HSPI adapter相同 C73 命令、4bpp 行、BUSY 与 abort 语义
调度与交互GPIO0 + 高有效 GPIO2 LEDGPIO0 + 低有效 GPIO2 LED安静时段、独立周期、Light-sleep、短按刷新、长按切布局和阶段灯码

ESP32 路线提供完整调试面、宽松的存储和成熟 C73 参考;1 MiB 路线证明内容层移出 MCU 后,同一产品可以落到极低成本、极小资源的 Wi-Fi 芯片。两条路线共用像素和恢复语义,平台差异被限制在网络、存储与 GPIO adapter。

GPT 参与设计的 3D 打印外壳

从机械约束生成参数化 CAD

我们让 GPT 参与约束整理、结构方案和 RhinoCommon 生成器设计,并输入一组可计算条件:GDEY073D46 裸屏外形 170.2 × 111.2 mm、玻璃厚度上界、FPC 宽度和伸出方向、C73 安装面、VHB 厚度、Bambu Lab X1 打印包络、PLA 多料、公差与无支撑方向。概念图只用于辅助观察,不承担参数化设计源的角色。

这些条件写入 paperboard_open_frame.py。脚本生成参数化 BRep、完整装配 3DM、打印布局、STL、参数 JSON、实体尺寸、装配交集与 STL 拓扑结果。修改屏幕净空、泡棉预压、背板厚度或底座角度时,关联零件和装配视图可以一起重建,避免手工 STL 成为唯一设计源。

零五金开放式结构

成品只包含三件 PLA 打印件:前框、整体背板和单件无胶落座底座。结构不使用螺钉、螺母、热熔螺母、金属铰链、弹性卡扣或紧配合销;前框与背板使用既有的 3M VHB 5608N,底座依靠宽松开放鞍座承托,整块屏幕总成可以向上直接取出。

组装后的成品观感

Paperboard 三件式 3D 打印外壳组装产品渲染
基于 Rhino 装配前、侧、斜视图生成的成品观感渲染:薄前框、裸屏总成与 68° 开放式桌面支架,屏幕保持空白。

这张产品图用于展示组装后的比例、材质和桌面姿态。生成式渲染对底座梁件做了视觉化简;前框厚度、鞍座位置、三角桁架、横梁和电子板空间以参数化 Rhino 模型及下面两张 CAD 装配图为准。

Paperboard 外壳与底座 Rhino 斜视装配图
Rhino 后侧斜视:两处开放鞍座、三角桁架、C73 与 ESP32 参考空间同时可见。
Paperboard 68 度底座 Rhino 侧视装配图
Rhino 侧视:屏幕相对桌面固定为 68°,观察方向从前上方向下约 22°。

玻璃、FPC 与电子板分别处理

前框边缘、2.0 mm 四角逃角、前后成对泡棉和连续背板共同保护裸屏。有效显示区中央保持悬空,结构胶位于屏幕轮廓之外,装配压力沿 PLA 外圈硬止挡闭合,不通过胶带或背板翘曲夹紧玻璃。

背板底部使用贯通边缘的 36 mm 开放槽,给 25.5 mm FPC 留出自然下伸与弯曲空间。C73 是背面无器件的单面板,两片 20 × 5 mm 5608N 直接把它粘到背板平整电子侧;ESP32 放在右下开放区,杜邦线保留自然弯折和应力释放。

为 FDM 打印方向设计结构

桌面姿态固定为 68°。左右两组相同的 6 mm 宽三角桁架使用 2.4 mm 斜梁/底梁,配一根 146 × 2.4 × 2.4 mm 轻量横梁;闭合侧板从底边逐层收拢,底座以桌面接触面朝下即可无支撑打印。底座体积从厚底座方案的 12.755 cm³ 降到 8.253 cm³

打印件结构任务当前几何
front_bezel.stl保护显示面边缘、建立窗口与四角逃角、承载前侧泡棉23.497 cm³
backplate.stl保护玻璃背面、提供 FPC 通道、结构胶位与平整电子安装面23.924 cm³
drop_in_cradle_base.stl68° 桌面姿态、双鞍座、三角桁架与横向稳定8.253 cm³
三件合计完整开放式桌面结构55.674 cm³

切片基线为 Bambu Lab X1、0.4 mm 喷嘴、PLA、0.12 mm High Quality、0.20 mm 首层、4 道墙、15% Gyroid 和关闭支撑。生成器按每个相关打印表面向材料侧预留 0.20 mm 多料预算,打印件间配合同时扣除两侧误差;需要调整时修改独立参数并重新生成,不整体缩放 STL。

GPT 在这里承担了从机械语言到可执行几何规则的转译:屏幕尺寸、公差、玻璃受力、胶带拆卸、FPC 路径、重心和打印方向进入同一份代码模型,外壳因此能和电子方案一样被版本化、重建和审查。

架构迭代迁移了什么

技术阶段迁移内容保留下来的能力
端侧 coreESP32 完成采集、模型、排版和送屏扫描线渲染、七色顺序、最后有效状态、C73 时序
图片 Worker图片获取、裁切与七色量化移到云端PBF1 图片合同、双槽缓存、photo 像素基线
全帧 Worker字体、天气行动面板、信息布局和图片合成为完整页面多字号中文、三种布局、云端快速视觉迭代
设备地区与调度地区四元组、配置事务、安静时段和布局周期进入共享合同设备自主位置配置、无配置 splash、成功手动刷新周期重对齐
render-onlyMCU 删除业务数据源和页面实现低内存流播放、双 CRC、原子缓存、本地错误覆盖
多 MCU平台无关帧/缓存/C73 模块配 ESP-IDF 与 ESP8266 RTOS SDK adapter独立版本线复用同一 PBF1、配置与控制语义
多云 adaptercreateWorker() 共享应用核心组合 Cloudflare DO/Images/Wasm 与 EdgeOne Node/Sharp/JS保持同一 HTTP/PBF1 合同,同时显式保留状态能力差异
参数化外壳GPT 把机械约束写入 RhinoCommon 生成器前框、背板、底座、3DM/STL/JSON 同步重建

core 仍然保留参考价值。photo 的 C 渲染输出可以和 Worker 做逐像素比较,主机 sink 继续复现屏幕像素路径,最早形成的刷新与恢复语义也保护着 render-only。当前主线只维护一套页面实现:内容进入 Worker,可信播放进入共享固件,物理安装进入参数化外壳。

一套围绕稳定边界组织的软硬件系统

Paperboard 的稳定边界是 800×480 七色完整帧。边界上方,共享 Worker 核心可以持续更换字体、天气视觉、数据源和图片策略,再由 Cloudflare 或 EdgeOne adapter 组合平台能力;边界下方,三种 MCU 复用帧校验、双槽提交和 C73 输出;设备外部,GPT 参数化外壳把裸玻璃、FPC、电子板和打印方向纳入同一套结构约束。

这条路径让一块更新缓慢、内存敏感的电子纸获得了云端页面的迭代速度,同时保留嵌入式设备需要的确定性:收到完整帧才刷新,断网仍有画面,换 MCU 不重写业务页面,改外壳尺寸也不从网格模型重新开始。