LVGL实时曲线:环形缓冲、抽取与可信时间轴

先保证时间含义,再把曲线画出来

传感器稳定采样,界面却不规则刷新,如果每次刷新只追加一个值,曲线看起来平滑,横向间距却不再代表采样时间。应先分开采集、历史存储和显示。本文采用LVGL 9.2文档,并以v9.2.2核对图表类型及接口,讨论数据正确性,不提供实测帧率优化结论。

实现依据来自LVGL官方仓库,控件约定见9.2图表说明。采样意义、缺口处理和时间标签仍由应用提供。即使控件绘制的坐标完全合法,应用若没有定义这些规则,也可能给读者传达错误的工程结论。

带时间戳采样进入原始环形区,一致快照经抽取后进入GUI独占数组,并保持轴时间一致。
原创工程概念图,表达设计依赖,不代表已经实测的实现。

采集不要依赖刷新时刻

每个采样记录应保留序号或时间戳,以及有效性标记。为了保存历史,采集路径不应等待GUI定时器。可以使用有界环形缓冲区保存最近数据,并明确覆盖或背压策略。如果数据进入环形区之前就已丢失,应保留丢样计数或不连续标记,不能把幸存数据假装成时间上相邻的样本。

按观察时长和采样率决定原始历史容量,再按视觉需求决定显示点数,这两个容量不同。例如假设每秒一百次采样、保存三十秒,需要三千条原始记录,之后还要计算元数据和对齐开销。这个算术不代表具体RAM占用或实际刷新性能。变采样率数据必须保留时间戳,仅凭点数不能确定稳定的时间跨度。

外部图表数组必须有明确拥有者

LVGL可以通过lv_chart_set_ext_y_array()使用应用提供的纵轴数组。v9.2.2头文件规定参数为int32_t指针,数组必须足以容纳配置的全部点。图表保留的是指针,所以临时局部数组不合适。改变点数却没有同步调整实际分配长度,可能使一次界面设置变成越界访问。

绘制期间不能让ISR或采集任务同时覆盖同一外部数组。一个容易审查的策略是GUI独占显示数组,从采集环形区复制一致快照;另一种是明确同步的缓冲区交接。无论哪种方式,数值和元数据都应来自同一代快照。更新外部数据后按接口约定调用lv_chart_refresh(),但刷新请求本身不会解决并发所有权问题。

抽取策略取决于曲线要回答的问题

多个原始样本落到同一个横向像素列时,每隔十点保留一点可能完全漏掉短峰。若目标是发现超限,按显示时间桶保留最小值和最大值通常更合适。连接极值时还应保留它们先后顺序,避免制造不存在的折返。平均值适合趋势概括,却会主动压低突变,必须说明这是经过处理的数据。

LVGL文档介绍了折线点数超过横向像素时的特殊绘制方式,但渲染器无法恢复上游抽取时已经删除的峰值,也不能替代放大查看时需要的原始历史。应在数据模型边界定义抽取过程,保留时间桶范围,并让游标详情说明显示的是原始点、均值还是极值。视觉上更平滑,不等于诊断信息更完整。

更新模式与时间轴一起设计

图表提供平移和循环更新模式。平移模式让新值进入右侧,旧值在逻辑序列中推进;循环模式则按滚动扫描方式覆盖位置。它们是显示策略,不是经过时间的定义。循环回绕时,应标明写入位置或不连续边界,避免读者把尾部到首部当作连续趋势。

普通折线通常按点序号分配横向间距。若时间戳不规则,可以重采样到已经说明的规则时间网格并保留缺口,或使用具有真实相对时间坐标的X/Y散点表示。v9.2.2的lv_chart_set_next_value2()用于提供散点横纵坐标。绝对时间若会超出控件坐标范围或损失精度,应留在应用模型中,再从同一个时间原点生成轴标签。

显示缺失,并验证历史窗口

LV_CHART_POINT_NONE可按图表文档约定跳过点或线段。使用零填补之前,必须先确定缺失数据含义,因为零也可能是真实测量值。长时间暂停或时钟跳变后,应明确开始新段或重建可见窗口,不要只因两个值在数组中相邻,就把旧数据和新数据直接连起来。

建议用斜坡、单采样尖峰、常量、故意丢样区间和时间跳变组成测试序列。覆盖环形回绕、整块显示数组更新、支持时的缩放变化,以及持续采样期间改变尺寸。断言最早与最新可见时间、缺口标记、峰值保留和游标映射,并与原始合成序列对照。本文没有执行采集硬件、GUI模拟器或渲染基准测试。

验收检查

  • 采样率、刷新节奏、历史容量和显示点数分别配置。
  • 每个显示值有时间戳,或明确说明固定采样间隔。
  • 外部数组有效、容量正确,绘制时不会被并发改写。
  • 抽取保留当前诊断问题真正需要的信息。
  • 丢样、循环回绕和时钟变化不会形成虚假的连续性。
  • 游标文字、轴刻度与曲线来自同一份历史快照。

类似文章