编写墨水屏固件时,如何在残影和底灰之间取得平衡


下面将从原理、策略和具体实现三个层面来详细阐述如何取得平衡。

一、 理解问题的根源:残影 vs. 底灰

  1. 残影(Ghosting)

    • 成因:墨水屏的显示原理是带电的微胶囊(或微杯)中的黑白粒子在电场作用下移动。一次刷新后,总有一部分粒子由于静电力、范德华力等未能完全复位,残留了上一次的图像信息。
    • 触发场景:频繁的局部刷新、快速翻页后最为明显。
  2. 底灰(Background Fog/Ghosting)

    • 成因:为了彻底消除残影,最有效的方法是进行全局刷新,并施加一个强力的、反向的驱动波形。但这个强力过程有时会“过度驱动”,导致本应纯白的区域也带入了少量黑色粒子,使得屏幕看起来“发灰”,不够干净。
    • 触发场景:全局刷新(通常是全刷或A2刷新模式)之后。

核心矛盾减少残影需要更“强力”的刷新,而这往往会加重底灰;减轻底灰需要更“温和”的刷新,但这又会导致残影积累。

二、 核心平衡策略

既然用户无法手动选择,固件就需要一套自动的、动态的策略来决定何时、如何进行何种程度的刷新。

策略1:基于刷新次数和场景的动态刷新策略

这是最常用且最有效的方法。不要固定一个刷新模式,而是根据用户的操作历史和当前动作来智能切换。

  • 局部刷新(Partial Update)

    • 优点:速度快、无闪烁、功耗极低。
    • 缺点:会逐渐累积残影。
    • 应用场景连续翻页、光标移动、输入法打字等需要快速响应的场景。
    • 平衡策略设置一个局部刷新计数器(N)。例如,连续进行 N=5 次局部刷新后,强制在下一次刷新时进行一次全局刷新来清残影。这个 N 就是关键平衡点,需要通过实验确定。
  • 全局刷新(Global Update/Full Update)

    • 优点:能最大程度清除残影,显示效果最干净。
    • 缺点:速度慢、有全屏闪烁、功耗较高、可能引入底灰。
    • 应用场景
      1. 达到局部刷新计数器上限时。
      2. 从阅读界面跳转到完全不同的界面时(如从书籍到主菜单)。
      3. 长时间无操作进入休眠前。
      4. 用户执行了“刷新屏幕”之类的明确指令。
  • 自动/轻度全局刷新(Auto/Light Global Update)

    • 一些墨水屏控制器(如佳显、晶宏等)提供了介于局部和全局之间的模式。这种模式会进行全屏刷新,但使用的波形比深度全局刷新更温和。
    • 优点:清残影效果比局部好,但底灰比深度全局刷新轻。
    • 缺点:清残影能力不如深度全局刷新。
    • 应用场景:可以作为局部刷新计数器达到上限后的首选,提供一个折中方案。

流程图示例:

策略2:波形文件(Waveform)的优化与选择

墨水屏的驱动波形(LUT,Look-Up Table)是控制粒子运动的核心。固件工程师可以与屏厂紧密合作,针对特定屏幕优化波形。

  • 针对“残影”优化:波形中会包含更多、更强的“ shaking ” 或 “ reset ” 阶段,确保粒子完全归位。
  • 针对“底灰”优化:波形会更温和,减少过冲,但可能需要更长的刷新时间。

实现方法

  1. 准备多套波形:固件中可以内置多套针对不同场景优化的波形文件。
    • 快速波形(Fast):用于局部刷新,速度快,容忍一定残影。
    • 平衡波形(Balanced):用于自动全局刷新,在速度和清洁度间取得平衡。
    • 清洁波形(Clean):用于深度全局刷新,最大程度清除残影,可接受一定底灰。
  2. 根据策略1动态切换波形。例如,局部刷新用Fast波形,计数满后用的自动全局刷新使用Balanced波形,而跳转界面时使用Clean波形。

策略3:区域抖动与渲染优化

即使在全刷模式下,也可以通过图像处理来“欺骗”人眼,减轻底灰感。

  • 全局抖动(Global Dithering)算法
    • 在显示灰度图像或文字时,使用更优的抖动算法(如Floyd-Steinberg)。清晰的边缘和干净的灰度过渡可以减少视觉上的“脏乱感”,从而在心理上减轻对底灰的注意。
  • 字体抗锯齿
    • 为墨水屏特别优化字体渲染。过度的灰度抗锯齿在墨水屏上容易显得模糊,适当使用黑白色素渲染边缘,反而更清晰,也能间接改善底灰的观感。

三、 具体实现步骤建议

  1. 基础测试

    • 与墨水屏供应商获取完整的驱动手册和初始波形文件
    • 实现最基本的全局刷新和局部刷新功能。
  2. 定义场景和阈值

    • 确定你的产品有哪些主要场景(阅读、翻页、菜单、输入、休眠)。
    • 通过主观测试,确定一个可接受的局部刷新次数上限 N(例如5次)。这个值需要反复调整,让大多数用户在感觉到明显残影前,系统就已经自动清除了。
  3. 实现状态机

    • 在固件中实现一个简单的状态机,跟踪当前的刷新模式和计数。
    • 伪代码示例:

      static int partial_refresh_count = 0;
      #define MAX_PARTIAL_REFRESH 5
      
      void request_screen_update(update_type_t type, image_data data) {
        switch(type) {
          case PARTIAL_UPDATE:
            drive_with_partial_waveform(data);
            partial_refresh_count++;
            if (partial_refresh_count >= MAX_PARTIAL_REFRESH) {
              drive_with_balanced_global_waveform(data); // 使用平衡波形全刷
              partial_refresh_count = 0;
            }
            break;
      
          case FULL_UPDATE_CLEAN:
            drive_with_clean_global_waveform(data); // 使用清洁波形全刷
            partial_refresh_count = 0;
            break;
      
          case INIT_OR_SLEEP:
            drive_with_init_waveform(data); // 休眠或初始化用的特定波形
            partial_refresh_count = 0;
            break;
        }
      }
  4. 迭代与调优

    • 这是最关键的步骤。组织不同的人进行长时间的真实使用测试。
    • 收集反馈:“翻页时有没有鬼影?”“屏幕底色干不干净?”“闪烁是否频繁?”
    • 根据反馈,微调 MAX_PARTIAL_REFRESH 的值,或者尝试切换不同的波形文件。

总结

在没有用户手动选择的情况下,取得平衡的关键在于 “以智能的全局刷新,服务于流畅的局部刷新”

  • 核心思想:允许短期内为了速度而积累少量残影,但通过算法预测用户容忍极限,在合适的时间点(用户可能不会特别注意时)自动进行一次清理。
  • 技术手段动态刷新策略(计数器) + 多套优化波形 + 良好的图像渲染

通过这种自动化的、场景驱动的方式,可以在绝大多数使用场景下,为用户提供一个在残影和底灰之间取得良好平衡的、无感的优质体验。


收藏

扫描二维码,在手机上阅读

年读几百本书,总结出了这个墨水屏小技巧

嵌入式 Geek 手搓的电子日历和学生课表

评 论
请登录后再评论