跳转到内容

Nextion TFT LCD 显示

nextion 显示平台允许你使用 Nextion LCD 显示 (数据手册,iTead) 配合 ESPHome。

Nextion 显示

与 Nextion 显示的通信通过串行接口进行,因此你需要在配置中有一个 UART 总线 并配置 rx_pin 和 tx_pin。然后将这些引脚连接到 显示上相应的引脚。

Nextion 显示默认使用 9600 的波特率。你可以通过 在 Nextion Editor 中编辑 program.s 源文件来配置 Nextion 显示使用更高的速度。例如:

baud=115200 // 将波特率设置为 115200;其他受支持速率见 https://nextion.tech/instruction-set/
bkcmd=0 // 告诉 Nextion 不在命令上发送响应。这是当前的默认值,但以防万一可以设置

这允许与 Nextion 显示进行更快的通信,在使用 硬件 UART 时强烈建议使用。

WARNING

我们强烈建议仅使用 硬件 UART 配合 Nextion 显示。

使用软件 UART 已知会导致不可预测/不一致的行为。

如果必须使用软件 UART,请注意,波特率大于 9600 极有可能导致问题。

简而言之,避免将软件 UART 与 Nextion 显示一起使用。

# 示例配置条目
display:
- platform: nextion
id: nextion1
lambda: |-
it.set_component_value("gauge", 50);
it.set_component_text("textview", "Hello World!");
  • uart_id (可选, ID): 你希望为此显示使用的 UART 总线 的 ID。当你有多个 UART 配置时指定此项。

  • brightness (可选, percentage): 指定时,显示亮度将在启动时设置为该值。

  • lambda (可选, lambda): 用于在 Nextion 显示上渲染内容的 lambda。更多信息请参见 渲染 Lambda。这通常是空的。Nextion 的各个 组件几乎处理更新显示元素所需的所有功能。

  • update_interval (可选, Time): 调用 lambda 来更新显示的间隔。 默认为 5s。

  • id (可选, ID): 手动指定用于代码生成的 ID。

  • tft_url (可选, string): 下载显示固件更新的 TFT 文件的 URL(Nextion OTA)。请参见 Nextion 上传。

  • tft_upload_http_timeout (可选, Time): TFT 上传传输的 HTTP 请求超时。 适用于上传过程中每个单独的 HTTP 请求。范围:1-65535ms。默认为 4.5s。

  • tft_upload_http_retries (可选, int): TFT 上传期间瞬态 HTTP 失败的重试次数。 在 Arduino 上,这适用于初始连接请求。在 ESP-IDF 上,这适用于分块读取操作。 范围:1-255。默认为 5。

  • tft_upload_watchdog_timeout (可选, Time): 临时调整系统看门狗超时 在 TFT 传输过程中。原始超时在传输 完成时(无论成功与否)自动恢复。在慢速连接或传输大型 TFT 文件时可能有用。 除非你遇到由于 TFT 上传期间看门狗超时导致的设备重启,否则不要设置此项; 否则可能阻止设备因真正的问题而重启。仅在 ESP32 上可用。

  • touch_sleep_timeout (可选, int): 设置内部无触摸睡眠计时器,单位为秒。 范围:0(禁用)或 3-65535 秒(最大:约 18 小时)。值 1-2 自动校正为 3。 设置后,Nextion 将在指定的无触摸活动期间后自动进入睡眠模式。 此设置在设备重启或复位之前持续有效。注意:显示只能通过重启或通过配置 auto_wake_on_touch: true 唤醒。

  • start_up_page (可选, int): 设置 ESPHome 连接到 Nextion 时要显示的页面。(Nextion 默认在启动时显示第 0 页)。

  • wake_up_page (可选, int): 设置唤醒后要显示的页面

  • exit_reparse_on_start (可选, boolean): 在显示设置前请求 Nextion 退出活动重新解析模式。默认为 false。

  • on_setup (可选, Action): ESPHome 连接到 Nextion 后要执行的操作。请参见 Nextion 自动化。

  • on_sleep (可选, Action): Nextion 进入睡眠时要执行的操作。请参见 Nextion 自动化。

  • on_wake (可选, Action): Nextion 唤醒时要执行的操作。请参见 Nextion 自动化。

  • on_page (可选, Action): 页面更改后要执行的操作。请参见 Nextion 自动化。

  • on_touch (可选, Action): 触摸事件(按下或释放)后要执行的操作。请参见 Nextion 自动化。

  • auto_wake_on_touch (可选, boolean): 如果设置为 true,Nextion 将配置为触摸时从睡眠中唤醒。

  • max_queue_age (可选, Time): 排队命令在自动 移除前的最大年龄(毫秒)。这有助于防止延迟后执行过时的命令。设置为 0 以禁用基于 年龄的移除(命令仅受队列大小限制)。注意: 非常低的值(例如 <50ms)可能导致命令 因 ESPHome 的循环计时(约 16ms)而在传输前被丢弃。启用时推荐的最低值为 100ms。 范围:0-65535。默认为 8000(8 秒)。

  • startup_override_ms (可选, Time): 如果显示尚未响应对接握手,等待的毫秒数后强制将显示标记为就绪。 设置为 0 以禁用覆盖并无限期等待 握手。这对于启动序列较慢的显示或强制执行严格的握手要求很有用。 范围:0-65535。默认为 8000(8 秒)。

  • skip_connection_handshake (可选, boolean): 设置是否跳过初始显示连接握手过程。 设置为 true 时,连接将在不执行握手的情况下建立。这在 使用 Nextion 模拟器时可能有用。默认为 false。

  • on_buffer_overflow (可选, Action): 当 Nextion 报告缓冲区溢出时要执行的操作。请参见 Nextion 自动化。

  • command_spacing (可选, Time): 设置发送到 Nextion 显示的命令之间的最小时间。 更高的值有助于防止缓冲区溢出,但会导致界面更新变慢。 范围为 0-255ms。默认为 0ms(禁用)。

  • max_commands_per_loop (可选, integer): 限制每个循环周期处理的命令数量。 这有助于防止大量命令排队时堆栈溢出。 较低的值(例如 20 )可能有助于在受限环境中提高稳定性。

  • max_queue_size (可选, integer): 设置可以一次排队的最大命令数量。 达到限制时,新命令将被丢弃并记录警告。 这有助于防止内存溢出或引导时间崩溃,在发出大量命令的复杂设置中 快速连续发生时。如果不设置,队列大小无限。

Nextion 显示具有直接内置于显示中的专用处理器来执行所有渲染。ESPHome 简单地 向显示发送指令,告诉它如何渲染某物 和/或 什么要渲染。

首先,你需要使用 Nextion Editor 创建一个”TFT”显示文件并 “安装”到显示上,通常通过 SD 卡,你将”TFT”文件复制到 SD 卡然后插入显示 进行安装/更新。然后,在渲染 lambda 中,你可以使用各种 API 调用来填充 显示数据:

display:
- platform: nextion
# ...
lambda: |-
// 设置组件的"值" - 值始终是整数
// 例如,仪表使用 0 到 100 的整数表示其状态
it.set_component_value("gauge", 50);
// 设置组件的文本
it.set_component_text("textview", "Hello World!");
// 以格式化方式设置组件的文本
it.set_component_text_printf("textview", "The uptime is: %.1f", id(uptime_sensor).state);

NOTE

虽然你可以使用渲染 lambda,但大多数(如果不是全部)对 Nextion 的更新都可以由 单独的 Nextion 组件/平台处理。参见下文

请参见 格式化文本 了解 printf 格式化规则的介绍,以及 显示时间 了解 strftime 时间格式化的介绍。

有几种方法可用于 lambda 中;这些允许超越 简单显示更新的更高级功能。这里涵盖的方法太多了,更多详细信息请参见 API 参考:nextion.h。 下面列出了一些常用方法:

  • upload_tft :开始将新 TFT 文件上传到 Nextion 的过程;请参见下面的 上传 TFT 文件。
  • update_all_components() :所有组件将发布它们的状态。
id(nextion1).update_all_components();
  • update_components_by_prefix(std::string page) :这将发送任何component_name 匹配前缀的当前状态。像背景颜色这样的某些设置需要在页面更改时重新发送;这是一个很好的挂钩点。
id(nextion1).update_components_by_prefix("page0.");
  • 设置各种传感器状态(请参见下面的 队列类型):

    • set_nextion_sensor_state(NextionQueueType queue_type, std::string name, float state);
    • set_nextion_sensor_state(int queue_type, std::string name, float state);
    • set_nextion_text_state(std::string name, std::string state);

NOTE

下面的示例演示如何定义用户 API,以便 Home Assistant 通过代码向 Nextion 发送更新。

# 启用 Home Assistant API
api:
actions:
- action: set_nextion_sensor
variables:
nextion_type: int
name: string
state: float
then:
- lambda: |-
id(nextion1).set_nextion_sensor_state(nextion_type,name,state);
- action: set_nextion_text
variables:
name: string
state: string
then:
- lambda: |-
id(nextion1).set_nextion_text_state(name,state);
类型值
SENSOR0
BINARY_SENSOR1
SWITCH2
TEXT_SENSOR3
WAVEFORM_SENSOR4
NO_RESULT5

有多种 触发器 可用于你的 Nextion 显示。

此自动化将在与 Nextion 显示建立连接时触发。这发生在启动 之后,可能需要一些时间(几百毫秒)。它可用于启动完成后更改某些显示元素。例如:

wifi:
ap: # 创建设备名称和 MAC 地址的 AP,无密码
captive_portal:
display:
- platform: nextion
id: disp
on_setup:
then:
- lambda: |-
// 检查是否配置了 WiFi 热点
if (wifi::global_wifi_component->has_sta()) {
// 显示主页面
id(disp).goto_page("main_page");
} else {
// 显示 WiFi 接入点二维码以获取捕获门户,参见 https://qifi.org/
id(disp).goto_page("wifi_qr_page");
}

这些自动化将在睡眠或唤醒(分别)时触发。Nextion 在睡眠模式下不接收命令或 更新;这些触发器可用于处理这种情况。例如,你可以使用它们来 强制更新,在唤醒时刷新显示的内容。

此自动化在显示上更改页面时触发。这包括 ESPHome 发起的和 Nextion 发起的页面更改。ESPHome 通过调用 goto_page("page_name") 或 goto_page(page_id) 函数发起页面更改。Nextion 本身也可以作为对用户活动的反应(触摸 某些显示 UI 元素)或使用计时器更改页面。无论哪种情况,此自动化都可以用于更新新显示页面的 屏幕控件。

如果你完全拥有自己的 Nextion HMI 设计,并遵循在 Nextion Editor 中为 UI 组件设置 vscope 为”global”的最佳实践,你可能永远不需要这个触发器。然而,如果 不是这种情况,且某些/所有 UI 组件的 vscope 设置为”local”,on_page 将是你的补救方法 —— 它 允许你初始化相关组件的更新。

在更新组件之前,你需要知道 Nextion 正在显示哪个页面。x 参数将包含一个 指示当前页面 ID 的整数。

给定页面 ID,可以更新适当的组件。有两种可能的策略:

on_page:
then:
- lambda: |-
switch (x) {
case 0x02: // wifi_qr_page
// 在此处手动触发页面 0x02 上的控件更新
id(disp).set_component_text_printf("qr_wifi", "WIFI:T:nopass;S:%s;P:;;", wifi::global_wifi_component->get_ap().get_ssid().c_str());
break;
}

此自动化在 Nextion 显示上的组件被按下或释放时触发。

以下参数将可用:

  • page_id :包含发生触摸的页面 ID(整数)。

  • component_id :包含被触摸组件的 ID(整数)。你必须为 HMI 配置中的 UI 元素启用”发送组件 ID”的 Nextion Editor。

  • touch_event :“按下”事件时为 true,“释放”事件时为 false。

on_touch:
then:
- lambda: |-
ESP_LOGD("nextion.on_touch", "Nextion touch event detected!");
ESP_LOGD("nextion.on_touch", "Page ID: %i", page_id);
ESP_LOGD("nextion.on_touch", "Component ID: %i", component_id);
ESP_LOGD("nextion.on_touch", "Event type: %s", touch_event ? "Press" : "Release");

此自动化在 Nextion 显示报告串行缓冲区溢出时触发。发生这种情况时, Nextion 的缓冲区将继续接收新指令,但所有先前的指令丢失,Nextion 队列可能不同步。

此自动化将允许你优雅地处理这种情况;例如,你可以重复某些命令/更新 到 Nextion 或重启系统。

on_buffer_overflow:
then:
- lambda: |-
ESP_LOGW("nextion.on_buffer_overflow", "Nextion reported a buffer overflow event!");

你可以使用此 操作 来设置 Nextion 背光的亮度。

on_...:
then:
- display.nextion.set_brightness: 50%

或者,如果你有多个连接的 Nextion 显示,你可能需要使用长格式:

on_...:
then:
- display.nextion.set_brightness:
id: nextion1
brightness: 50%

这将使用为 tft_url 指定的文件更新(“OTA”)Nextion。

完成后,ESPHome 和 Nextion 都将重启。ESPHome 在上传过程中将无法响应,并且不会 进行日志记录或其他 自动化。此过程使用与 Nextion Editor 相同的协议,并且只传输 TFT 文件的必需部分。

WARNING

使用软件 UART 已知会导致不可预测/不一致的行为,并可能导致 更新过程失败。

如果你在使用软件 UART 时遇到更新过程问题(例如在 ESP8266 上),你 应该切换到 ESP32 或受支持的变体,它有更多的可用 硬件 UART。

你可以使用 Home Assistant 本身或任何其他 Web 服务器来托管 TFT 文件。使用 HTTPS(通常 推荐)时,你可能注意到上传速度降低,因为加密消耗了微控制器上的更多资源。

可以在上传期间通过 tft_upload_http_timeout、tft_upload_http_retries 和 tft_upload_watchdog_timeout 配置选项来自定义 HTTP 超时、重试次数和看门狗行为。 这在慢速或不可靠的网络连接上可能有帮助。

# 带 TFT 上传参数的示例配置
display:
- platform: nextion
id: nextion1
uart_id: my_uart
tft_url: "http://192.168.1.100:8080/display.tft"
tft_upload_http_timeout: 20s
tft_upload_http_retries: 10
tft_upload_watchdog_timeout: 30s # 仅限 ESP32

我们建议使用 模板 来触发此过程。例如:

button:
- platform: template
id: update_nextion_button
name: Update Nextion
entity_category: diagnostic
on_press:
then:
- lambda: 'id(nextion1)->upload_tft();'

要从 Home Assistant 托管 TFT 文件,请在你的 config 目录中创建一个 www 目录(如果还不存在)。如果需要,你也可以为 TFT 文件创建子目录。

例如,如果文件位于你的配置目录 www/tft/default.tft 中,访问它的 URL 将为 http(s)://your_home_assistant_url:port/local/tft/default.tft

此库支持几种不同的组件,允许 Home Assistant、ESPHome 和 Nextion 之间的通信。

NOTE

如果 Nextion 处于睡眠状态或如果组件被设置为隐藏,即使发送了 更新,它也不会更新其组件。为了解决这个问题,在 Nextion 唤醒后,所有组件将向 Nextion 发送它们的状态。

除了配置了 page_id /component_id 选项的 Nextion 之外, 下面的示例说明了:

  • 轮询 Nextion 以获取更新
  • 从 Nextion 发送到 ESPHome 的动态更新
sensor:
- platform: nextion
nextion_id: nextion1
name: "n0"
component_name: n0
- platform: nextion
id: current_page
name: "current_page"
variable_name: dp
update_interval: 1s

注意第一个需要在 Nextion 显示的 HMI 代码/配置中包含自定义协议。请参见 单独的组件(链接如下)以获取更多详细信息。