从下单到收到货零零总总等了差不多两周。拆开包装的那一刻说实话并没有特别激动——需求拆解和方案选型在前面几篇里已经反复推演过拿到实物以后反而是一步步照着计划执行的过程。这一篇是 Status Deck 系列的第四篇核心就两件事把屏幕点亮把所有链路串起来跑通第一个 Demo。先解释一下 Status Deck 是什么。简单说就是一块放在桌面上的信息屏平时一直亮着展示当前时间、日期、天气、待办事项、系统状态这类信息。我给它起这个名字是因为它像驾驶舱里的仪表盘一样不需要打开电脑、点开各种应用抬头一扫就能看到今天有哪些安排、电脑负载高不高、天气要不要带伞。这个项目我定义成“全栈自造”意思是硬件选型、驱动移植、数据服务、界面渲染、外壳制作全部自己走一遍不买现成的桌面伴侣屏成品也不套用某个商业方案。这篇博客主要写给正在做类似桌面信息屏、或者准备从零接触 ESP32 驱动屏幕的朋友。如果你对“怎么点亮一块屏幕”“怎么让设备和本机服务通信”“硬件调试有哪些坑”这几个问题感兴趣那这篇的内容应该能给你一些直接能落地的参考。我尽量把每一步的为什么也讲清楚毕竟我踩坑的时候最缺的就是有人告诉我“这一步到底在图什么”。1. 等配件等了两周先把 Status Deck 的整体方案回忆一遍1.1 这个项目到底想解决什么问题在动手之前我先说说这个项目最初的出发点。我桌面上常年开着电脑但很多信息其实并不需要打开电脑才能看——比如时间、天气、今天有没有会议、后台服务是不是还活着。手机也能看但手机的问题是信息太分散而且动不动就被通知淹没。Status Deck 想做的就是把这些高频率、低深度、一眼就能看懂的信息聚合到一块专门的屏幕上。带着这个需求去反推硬件就有几个硬性指标屏幕要小、要长期点亮但发热不能夸张主控要联网整体的二次开发门槛不能太高最好断电重连之后能自动恢复工作。这些指标叠加起来用手机当屏幕就太重了用平板太贵用二手墨水屏阅读器又不够灵活。最后我把目光锁定在了一块小尺寸 SPI 彩色 TFT 屏加一块 ESP32 开发板这个组合上。1.2 硬件选型的取舍复盘先说主控。我选的是 ESP32 系列的开发板具体是哪个厂家出的其实无所谓引脚基本兼容。选它的理由有三点。第一自带 WiFi这是 Status Deck 的刚需因为数据要从本机服务或者网络接口拉取。第二I/O 口数量足够驱动一块 SPI 屏幕只需要六七个引脚剩下的还能接传感器或者按键。第三成本和功耗平衡得好整个系统跑起来功耗在几百毫瓦级别长时间开机不心疼电费。屏幕方面最开始犹豫过要不要用电子墨水屏。墨水屏的优点非常明显——断电后画面不消失、看起来像纸质、非常省电。但它有个致命弱点刷新速度慢局部刷新还容易留残影。Status Deck 是高频信息展示场景我希望它能跑到每秒刷新甚至每五秒刷新的程度墨水屏刚性不满足。最后选了 3.5 寸 320x480 分辨率的 SPI 彩色 TFT 屏驱动 IC 是很常见的 ST7789 系列色彩表现和刷新速率都能接受价格也便宜。至于为什么不直接上树莓派加 HDMI 屏幕——树莓派资源更强但成本高两三倍体积也大还要跑完整系统对于一个固定显示几行文字的小屏来说大材小用。ESP32 这种单片机级方案反而更适合固定任务的场景稳定、启动快、坏了重烧固件就行。1.3 开箱之后不要急着接电先做这些检查硬件到了以后我第一反应是赶紧接上看看能不能亮。后来发现这么做容易出问题。屏幕这种娇贵的东西运输过程中最容易翻车的是排线折断、玻璃碎角、引脚弯针。我这次收到的屏外观正常但是有一个小细节差点让我多折腾一晚上——板子背面的丝印标注和实际驱动 IC 型号不完全一致好在从排线接口数量和 PCB 上的印刷字符能判断出真实型号。这里分享一个开箱检查清单先看屏幕玻璃表面有没有裂纹、坏点区域。看 FPC 排线和 PCB 焊盘有没有松脱、氧化。检查所有排针是否笔直有没有弯折、缺针。记录板子上丝印的型号、版本号、日期拍照存档。特别留意 VCC 引脚旁边印刷的电压值是 3.3V 还是 5V这个后面接线直接决定生死。不要忽略这一步。我见过有人拿到屏直接接 5V结果屏幕稳压芯片烧了的案例。检查只花五分钟能省下后面排查问题的几个小时。2. 点亮屏幕前的前置动作环境、接线和驱动确认2.1 开发环境搭建二十来分钟就能完成屏幕和主控都到手了接下来要做的并不是立刻写代码而是先把开发环境准备好。我在 Windows 上用的是 Arduino IDE 搭配 ESP32 支持包这个流程现在很成熟了。安装好 IDE 之后在开发板管理器里添加 ESP32 的板级支持包选择对应的开发板型号然后安装屏幕图形库。这里我先不点库名你在库管理器里搜 TFT 或者 GFX 关键词找一个支持 ST7789 驱动、Star 数高、更新活跃的图形库就可以。差别主要体现在初始化序列和字体渲染上库选对了后面会省心很多。还有一个经常被忽略的点是 USB 串口驱动。ESP32 开发板上的 USB 转串口芯片常见的有 CP2102 和 CH340 两种。如果你把开发板插到电脑上设备管理器里完全找不到新的 COM 口大概率就是缺了对应的驱动。这个问题和代码没关系先装好驱动再继续。开发环境里有几个参数值得注意。板型选错会导致编译失败或者烧录后跑飞比如带 PSRAM 和不带 PSRAM 的型号分区表不一样。烧录设置里的 Flash Mode、Flash Size 一般保持默认就能用但是如果你的板子老出烧录失败可以把上传速度从 921600 降到 115200 再试低速更稳。2.2 接线不是按颜色来是按功能来接线看起来简单杜邦线一插就行但这里最容翻车的恰恰是这一步。市面上的 SPI 屏幕引脚定义大致相同但顺序和命名会有差别。有的叫 SCK 有的叫 SCL有的叫 SDA 有的叫 MOSIDC 有的写成 RSCS 有的写成 SS。不要只看名字要对应到功能上去理解SCK 是时钟MOSI/SDA 是主出从入的数据线CS 是片选DC 是数据/命令切换。我这次的接线方案是ESP32 的 GPIO18 接 SCKGPIO23 接 MOSISDAGPIO5 接 CSGPIO27 接 DCGPIO26 接 RSTGPIO4 接背光 BL。VCC 和 GND 按屏幕丝印接。放一张引脚对照表方便你参考屏幕引脚功能ESP32 GPIO备注VCC电源3.3V 或 5V 视屏而定具体电压看丝印别猜GND地GND共地必须接SCK/SCLSPI 时钟GPIO18与 MOSI 配套MOSI/SDASPI 数据GPIO23主出从入CS/SS片选GPIO5低电平有效DC/RS数据/命令GPIO27也经常标作 A0RST/RESET复位GPIO26可接低电平复位BL/BLK背光GPIO4不接默认亮或不亮关于电平和电压这里要重点说两句。ESP32 的 GPIO 输出是 3.3V 电平逻辑很多 TFT 屏幕的逻辑电平也能兼容 3.3V这部分直接连没问题。但屏幕的 VCC 供电可能是 3.3V 也可能是 5V一定要看丝印或者问卖家要规格书。如果你给屏幕的逻辑部分供了 5V 而主控是 3.3V那么高电平信号线理论上存在倒灌风险哪怕短期能工作也不建议长期这么干。稳妥的做法是 VCC 按屏幕要求接所有信号线保持在 3.3V 逻辑。2.3 不要一上来就跑官方 Demo先做一个最素的最小点亮我之前犯过一个错误下载了官方示例直接改引脚结果屏幕上什么都没有白屏一块。原因可能是屏幕驱动 IC 和示例默认的不匹配也可能是初始化序列不对。后来我改了策略先做一个“最素”的测试代码目的只有一个——确认屏幕能显示纯色。这一步的代码很短核心逻辑就是初始化图形库、填充全屏黑色、再填充全屏红色。如果红屏显示出来说明接线、供电、驱动初始化全部通过整个屏幕链路已经通了。如果白屏优先检查 CS 和 DC 这两根线如果花屏优先怀疑 SPI 频率太高或者初始化尺寸不对如果完全没背光先查 BL 引脚。这种从简到繁的方法排障成本最低。#include Arduino_GFX_Library.h #define TFT_SCK 18 #define TFT_MOSI 23 #define TFT_CS 5 #define TFT_DC 27 #define TFT_RST 26 #define TFT_BL 4 Arduino_Data *bus new Arduino_ESP32SPI(TFT_DC, TFT_CS, TFT_SCK, TFT_MOSI, -1); Arduino_GFX *gfx new Arduino_ST7789(bus, TFT_RST, 1 /* rotation */, true /* IPS */, 240, 320, 0, 0); void setup() { pinMode(TFT_BL, OUTPUT); digitalWrite(TFT_BL, HIGH); gfx-begin(); gfx-fillScreen(BLACK); delay(1000); gfx-fillScreen(RED); } void loop() {}我这里把宽高参数写成 240x320 而不是 320x240是因为竖屏是状态面板最常见的形态。rotation 参数不同宽高顺序会交换。如果你的屏表现是红屏但上下颠倒改 rotation 就能转过来。3. 屏幕真正亮起来从纯色画面到能写字的正式显示3.1 第一行代码之后理解屏幕是怎么被驱动的屏幕亮起来之后很多人的下一步是继续堆代码但我觉得这里值得停下来理解一下屏幕的驱动原理。TFT 屏幕本质上是一个像素点阵每个像素由红绿蓝三个子像素组成。主控要通过 SPI 接口把每个像素的颜色数据按照固定时序刷到屏幕驱动 IC 的显存里。驱动 IC 再负责把显存内容对应到物理像素上点亮。这意味着两件很重要的事。第一你写代码是在往一块“显存画布”上画画驱动 IC 会负责把画布显示出来。第二如果显存尺寸和屏幕物理分辨率不匹配比如你告诉驱动 IC 这是 240x320 的屏但实际面板是 320x480那么显示内容就会错位、偏移甚至只有一部分能看见。所以初始化那一步的宽高参数不能乱填要以屏幕实际分辨率为准。有了这个认知之后你在调试花屏、偏移这类问题时会更有方向感花屏倾向于 SPI 通信问题偏移倾向于显存尺寸或坐标偏移问题颜色不对倾向于 BGR 颜色顺序问题。这些后面会展开讲。3.2 画几个基本图形确认坐标体系没问题纯色显示正常之后我会习惯性画几个基本图形验证坐标体系。具体做法画一个十字线交叉在屏幕中心画一个矩形框贴住屏幕边缘再逐字节填充一个渐变色条。如果这些图形都准确出现在预期位置说明坐标方向没有错位。十字线可以用 drawLine 画两条线一个从屏幕左上到右下一个从左下到右上矩形用 drawRect设置 0,0 到 239,319。如果你看到矩形四条边没有全部贴边而是有一边留白或者被截断那就是坐标偏移。这种情况在 ST7789 这类驱动 IC 上很常见因为它们某些分辨率的面板需要在初始化时指定显示区域的偏移量。图形库构造函数里往往有对应的 offset 参数调一下就能让画面居中。字体显示也是同一个道理。我用图形库的 setCursor 设置文字起点然后调用 println 输出一行文字。注意不同图形库对 Cursor 坐标的定义有差别有的是左上角基准有的是左下角基线基准。我第一次用的时候默认文字在某库中是基线基准结果字符全都偏到画布外面去了。遇到这个情况时去看库的说明文档或者直接实验几个坐标很快就能摸清。3.3 花屏、缺色、偏移这三个问题一次说清这个阶段最容易遇到三个问题我挨个说排查方法。第一个是花屏屏幕上全是雪花点、横条纹或者杂乱的颜色。这种问题 80% 是 SPI 通信不稳定。排查步骤先看杜邦线是否插紧特别是 SCK 和 MOSI 这两根接触不良时花屏尤其明显然后把 SPI 频率从默认的 40MHz 往下降到 26.67MHz 甚至 20MHz很多屏在高速 SPI 下信号质量跟不上降频之后立刻正常。这个原理和网线的传输距离类似频率越高对线路的阻抗匹配要求越苛刻杜邦线这种物理连接方式本身就限制了高速传输。第二个是颜色不对比如红色显示成了蓝色肤色显示成了诡异的效果。这基本是 BGR 颜色顺序问题。ST7789 这类驱动 IC 支持 RGB 和 BGR 两种颜色排列方式屏幕面板出厂时可能用的是 BGR而图形库默认按 RGB 处理结果就是红蓝互换。解决办法是在初始化参数里找到 rgb order 相关的标志位翻转一下。我曾经在这个问题上卡了整整一个晚上最后发现只需要改一个布尔值。第三个是画面偏移显示内容整体向左或向上移动了一块。原因是面板分辨率小于驱动 IC 的最大支持分辨率剩下来的行列没有被使用需要在初始化时告诉驱动 IC 偏移量。具体做法是在构造函数里传入 offset_x 和 offset_y把画面拉回物理面板的起始坐标。我这次用的屏就要求 offset_x0、offset_y20不设的话显示内容整体偏上。4. 跑通第一个 Demo本机数据源 WiFi 拉取 定时渲染4.1 Demo 需求定义不用做多漂亮但链路必须完整屏幕能显示图形和文字了接下来就是本篇文章的重头戏——跑通第一个真正的 Status Deck Demo。我给自己定的目标是屏幕上至少出现四类信息包括当前时间日期、一条天气描述、两条待办事项、一条系统状态数据。这个目标刻意做得不够华丽因为第一版的核心是验证数据链路而不是美化 UI。数据链路的设计是这样的本机跑一个 Python 服务提供一个 HTTP 接口返回 JSON 格式的状态数据ESP32 通过 WiFi 连上局域网周期性地请求这个接口拿到 JSON 后用 ArduinoJson 解析再把解析结果渲染到屏幕的各个区域。这套结构非常通用即使以后要接入真实天气 API也只是在 Python 服务里多写一个请求ESP32 端几乎不用改。为什么不让 ESP32 直接请求外网天气 API原因很简单——外网接口往往有访问频率限制参数处理也更复杂调试的时候有太多变量。先把本机服务作为稳定的数据源等链路跑通了再逐步替换成真实数据源。这是分层解耦的思路每一步只验证一个环节出了问题能快速定位。4.2 本机数据服务用 Python 标准库十几行搭起来先写数据服务端。我这里故意不引第三方框架就用 Python 标准库里的 http.server这样任何一台装了 Python 的机器都能直接跑不需要安装 Flask 之类的东西。接口路径设计成 /api/status返回一个 JSON 对象字段包含更新时间、日期、天气描述、待办数组、系统指标。下面这段代码可以直接保存为 status_server.py 运行。from http.server import BaseHTTPRequestHandler, HTTPServer import json import time def build_status(): return { updated: time.strftime(%H:%M:%S), date: time.strftime(%Y-%m-%d), weekday: time.strftime(%A), weather: 晴 27C, todos: [下午两点项目同步会, 给屏幕画外壳图], metrics: {cpu: 23, mem: 58} } class Handler(BaseHTTPRequestHandler): def do_GET(self): if self.path /api/status: body json.dumps(build_status()).encode(utf-8) self.send_response(200) self.send_header(Content-Type, application/json; charsetutf-8) self.send_header(Content-Length, str(len(body))) self.end_headers() self.wfile.write(body) else: self.send_response(404) self.end_headers() if __name__ __main__: server HTTPServer((0.0.0.0, 8080), Handler) print(Status server running at :8080) server.serve_forever()运行之后在浏览器打开 http://127.0.0.1:8080/api/status 就能看到 JSON 数据。这里有个细节HTTPServer 的 address 参数写了 0.0.0.0这样才能允许局域网内其他设备访问。如果你只写 127.0.0.1ESP32 从网络访问就会被拒之门外。4.3 ESP32 端实现拉数据、解析、分区渲染数据服务就绪后回到 ESP32 端。这一部分代码比点亮屏幕复杂不少主要包括 WiFi 连接、HTTP 请求、JSON 解析和页面渲染四个模块。我建议把渲染部分抽成一个独立的 drawStatus 函数这样主循环的逻辑会非常清晰保持连接、到点拉数据、拉完画屏幕。WiFi 连接这部分没什么好说的调库函数传 SSID 和密码即可。需要注意的一点是如果 WiFi 连接失败不要无脑重试导致主循环卡死而是要做一个状态标志让屏幕显示“网络未连接”同时继续尝试重连。HTTP 请求我用的是 HTTPClient 库。关键事项是设置超时时间不然网络不通的时候请求会一直挂着。JSON 解析用 ArduinoJson 库版本不同 API 略有差别新版本推荐用 JsonDocument 而不是老版的 DynamicJsonDocument。解析出来的字段通过 .asconst char*() 或者 .asint() 读取然后格式化成字符串画到屏幕上。渲染部分我按三个区块划分顶部显示日期和星期中部显示时间下半部分显示待办事项和系统指标。每个区块先 fillRect 填充底色清掉旧内容再重新绘制文字这样可以避免画面出现噪点。清区再画字局部刷新只更新变化部分比整屏清掉重画快很多看起来也更专业。#include WiFi.h #include HTTPClient.h #include ArduinoJson.h #include Arduino_GFX_Library.h const char* ssid 你的WiFi名字; const char* password 你的WiFi密码; const char* apiUrl http://192.168.1.100:8080/api/status; #define TFT_SCK 18 #define TFT_MOSI 23 #define TFT_CS 5 #define TFT_DC 27 #define TFT_RST 26 #define TFT_BL 4 Arduino_Data *bus new Arduino_ESP32SPI(TFT_DC, TFT_CS, TFT_SCK, TFT_MOSI, -1); Arduino_GFX *gfx new Arduino_ST7789(bus, TFT_RST, 1, true, 240, 320, 0, 0); unsigned long lastFetchTime 0; const unsigned long fetchInterval 30000; // 30秒刷新一次 void fetchAndDrawStatus() { HTTPClient http; http.begin(apiUrl); http.setTimeout(5000); int code http.GET(); if (code ! 200) { gfx-fillScreen(BLACK); gfx-setCursor(20, 150); gfx-println(API request failed); http.end(); return; } String payload http.getString(); http.end(); JsonDocument doc; DeserializationError err deserializeJson(doc, payload); if (err) { gfx-setCursor(20, 150); gfx-println(JSON parse error); return; } const char* date doc[date]; const char* weekday doc[weekday]; const char* weather doc[weather]; int cpu doc[metrics][cpu]; int mem doc[metrics][mem]; gfx-fillRect(0, 0, 240, 40, BLACK); gfx-setCursor(10, 10); gfx-println(date); gfx-setCursor(10, 26); gfx-println(weekday); gfx-setCursor(10, 60); gfx-println(weather); gfx-setCursor(10, 120); gfx-println(CPU: ); gfx-println(cpu); gfx-setCursor(10, 150); gfx-println(MEM: ); gfx-println(mem); } void setup() { pinMode(TFT_BL, OUTPUT); digitalWrite(TFT_BL, HIGH); gfx-begin(); gfx-fillScreen(BLACK); WiFi.begin(ssid, password); gfx-setCursor(20, 150); gfx-println(Connecting WiFi...); while (WiFi.status() ! WL_CONNECTED) { delay(500); } gfx-fillScreen(BLACK); } void loop() { unsigned long now millis(); if (now - lastFetchTime fetchInterval) { lastFetchTime now; fetchAndDrawStatus(); } }上面这段代码是简化版主要展示链路如何打通。实际用时我会把字体改成更大字号增加待办列表的分行显示并且把刷新频率降到 10 秒一次便于肉眼观察变化。第一次跑通的时候屏幕从红屏切到显示日期、天气和 CPU 数值的那一刻说实话还挺有成就感的。一个能用的小系统跑通了。4.4 刷新策略和局部渲染的几个小技巧Demo 跑通之后值得花点时间优化刷新策略。一种简单做法是每 30 秒整屏清空重画这种做法实现最快但有个问题清屏的瞬间屏幕会闪一下而且视觉上“跳动感”很强。更好的做法是分区刷新只有时间这种秒级变化的数据才高频更新天气预报这种小时级变化的低频更新日期更是每天更新一次就够了。我采用的分区逻辑是顶部日期区域每小时刷一次中部天气区域每十分钟刷一次时间数字每分钟刷一次系统指标每三十秒刷一次。每个区域单独 fillRect 清底再重画相邻区域之间保留几个像素的间隔避免清区时误伤。还有一个细节在画文字之前先填充与底色一致的颜色可以消除文字边缘的残影。不要小看这个细节长期显示的面板如果每次刷新都全屏闪一下看十分钟眼睛就累了。5. 硬件折腾期最容易翻车的细节和排查办法5.1 供电问题花屏重启的头号嫌疑人我做过的多数嵌入式小项目里供电引发的故障能占一半以上。ESP32 的功耗特点是瞬态峰值高尤其是 WiFi 发射瞬间电流可以冲到 300mA 到 500mA。如果电源或者 USB 线压降太大WiFi 一启动电压就被拉低结果是屏幕刚亮起就重启或者画面花掉。排查方式很简单接一个万用表测量开发板 3.3V 引脚上的电压在 WiFi 连接的一瞬间观察电压跌落幅度。如果低于 3.2V基本就是供电不足。解决方法是换一根短而粗的 USB 线或者直接用 5V 适配器供电而不是插在电脑机箱前置 USB 口上。如果你的屏幕还有独立背光驱动尤其注意背光开启时的电流冲击很多屏背光瞬间电流能达到几十毫安和主控叠加后更容易出问题。5.2 引脚选择不是随便挑有的脚不能做输出ESP32 有几个 GPIO 是输入专用引脚比如 GPIO34 到 GPIO39这类引脚没有内部上拉也不支持输出模式。如果接线时图省事把 DC 或者 CS 接到这些引脚上代码编译没问题但运行时信号根本不会输出屏幕自然不工作。另外有些 GPIO 在上电瞬间有特殊状态比如 GPIO12 是 strapping pin如果接的设备影响启动电平可能导致开发板无法正常启动。虽然我这次没有遇到这个问题但保险起见用 GPIO18、19、23、5、27、26 这类常规引脚做 SPI 总线是经验之谈。引脚选择要在接线前想好不要焊完了才发现引脚冲突那就麻烦了。5.3 尺寸、偏移和旋转参数一错全错屏幕显示相关的问题很少是单点故障往往是尺寸、偏移、旋转三个参数叠加出错。一开始我把一块 320x480 的屏当成 240x320 来初始化结果画面不仅偏移连分辨率都不对字全是花的。后来我把这三个参数拆开验证先填纯色判断扫描区域是否正确再画边缘矩形判断偏移量最后旋转参数试四组值找到物理上下方向。这样逐个击破比一次改三个参数要容易定位得多。我把这次折腾中遇到的高频问题整理成了一个表格方便你对照排查症状可能原因优先排查动作白屏无显示初始化序列未执行或驱动型号不匹配确认实际驱动 IC检查 RST 接线花屏/雪花SPI 频率过高或接触不良降频到 26.67MHz重插 SCK/MOSI红蓝互换BGR 顺序配置不对翻转 rgb order 标志位画面偏移面板分辨率小于驱动 IC 默认值设置 offset_x / offset_y显示上下颠倒rotation 参数不对试 rotation 0~3开机反复重启供电不足或 WiFi 电流拉低电压更换电源测量 3.3V 跌落5.4 不要迷信默认配置数据手册和丝印才是最终依据最后说一个习惯性建议拿到任何一块屏幕第一件事就是找到它的数据手册或者至少是配套的资料包把驱动 IC 型号、通信接口、电压要求、分辨率确认三遍。不要指望所有屏幕都能套同一套默认代码哪怕型号名字差不多不同批次的面板也可能在颜色顺序、偏移量上有差异。我在这次项目中就遇到过丝印型号和实际驱动 IC 不一致的屏如果完全信丝印可能到现在还在白屏。我的做法是把屏幕的丝印拍照、型号记录在项目文档里然后写一个简单的测试固件专门用来验证分辨率、颜色顺序和偏移量。以后只要换屏先跑这个测试固件参数确认了再套正式代码。这个习惯帮我省了不少时间。最后分享一点实际体会从硬件到货到跑通第一个 Demo我前后花了大概两天时间。第一天主要是接线、点屏、排障第二天搭数据服务、写渲染逻辑。真正让我觉得这个项目进入正轨的不是屏幕亮起来的那一刻而是数据链路完全打通的那一刻——屏幕上的时间会跟着我的电脑同步更新天气变化后重新拉一次接口就显示新内容待办事项改了 JSON 里的数组屏幕上也跟着变。虽然 UI 还很粗糙但整个系统已经是一个完整的闭环了。这个阶段的体会是做一个 Status Deck 这样的东西最难的不是某个单一技术点而是把所有环节串起来的能力。每一个环节单独看都简单但串联过程中会遇到各种意想不到的问题比如 WiFi 连接超时、JSON 解析失败、屏幕闪烁、IP 地址变化。我的建议是把问题拆小一次只验证一个环节点亮屏幕就只验证显示联网就只验证 HTTP 请求解析就只验证 JSON。等每个单点都可靠了再合起来跑整链路。下一步我打算做三件事把 UI 布局调好看增加真实的天气和日历数据源然后设计一个外壳把屏幕和开发板装进去。外壳做完之后这个 Status Deck 就能正式摆在桌面上长期运行了。回头等外壳做好了再来更新第五篇。
阅读完成 · 觉得有帮助?