LCD 渲染:避开整屏重绘

PipeMonitor 的现场 LCD 同时显示多个传感器的实时数值。最容易踩的坑就是每次刷新都整屏重绘,眼睛看上去一直在抖。

LCD 模块在 applications/PipeMonitor/LCD/ 下,做了几件事:

  • 静态布局一次绘制完成:标题栏、表格框、单位标签等不会变的部分只画一次
  • 动态行脏数据局部重绘:每个测点维持一份”上次显示的值”,只有当新值与上次显示不同(或精度位变化)时,才用背景色矩形把那一行擦掉再画新值
  • 告警以特殊颜色显示:当采集层报告该测点处于异常状态(连续超时、CRC 错误、量程溢出)时,那一行切换到告警色

这样一来,正常工况下屏幕几乎”看不出”在刷新;告警发生时反而能一眼看到。

UI 线程不直接访问 Modbus 总线。它只从测点的内存快照读最新值,快照由采集线程更新,互斥锁保护。

LittleFS 文件系统

为什么不直接拿 RAW Flash 顺序写:

  • 现场设备会经常掉电
  • 单次写入要保证原子性,至少在一行 CSV 内不能被截断
  • 老数据需要按时间滚动,不能写满 Flash 后停摆

LittleFS 自带掉电安全和磨损均衡,刚好满足这些条件。packages/ 目录下接入了 RT-Thread 的 LittleFS 软件包,挂载到一段独立的 Flash 区域。

measurements.csv 字段设计

存储线程把每次采集事件序列化成一行 CSV。字段顺序固定如下:

timestamp, uptime_ms, flow_lpm, total_l, velocity_ms,
pxw_temp_c, pxw_pres_mpa,
temp_4_1_c, temp_4_2_c,
temp_5_1_c, temp_5_2_c, temp_5_3_c, temp_5_4_c
字段含义
timestamp现场时钟时间戳
uptime_ms系统上电后毫秒数,用于跨重启对齐
flow_lpm / total_l / velocity_ms超声波流量计三项
pxw_temp_c / pxw_pres_mpaPXW 温度与压力
temp_4_*_cPT100 4 通道四路温度
temp_5_*_cPT100 5 通道四路温度(保留位)

刷盘策略:批量 + Rotate

存储线程不会每次采集都立刻 fsync:

  • 批量刷盘:内存里维护一段写入缓冲区,按定时阈值或缓冲区水位触发刷盘
  • 文件 Rotate:单文件超过预设大小后自动切换到下一个文件名,老文件按 FIFO 删除,避免写满 Flash

总线错误时的保护策略

读写失败的字段不能写一个看似合理的”假值”,否则会污染历史数据。处理原则:

  • 空值跳过:失败字段写空字符串(,,),CSV 在解析时识别为缺失
  • 哨兵值标记:对于不能用空值表达的语义错误(例如温度负数极值),写一个特定的哨兵值(例如 -9999),辅助事后分析

这样后续在 PC 端做曲线/告警分析时,可以清楚区分”无数据”和”采集异常”两种情况。

后续阅读