UART 总线
UART 是许多设备的常见串行协议。例如,当您将二进制文件上传到 ESP 时, 您可能已经使用 UART 访问了芯片。UART(或在 Arduino 中通常也称为 Serial)通常 由 2 个引脚组成:
- TX: 此线用于向另一端的设备发送数据。
- RX: 此线用于从另一端的设备接收数据。
请注意,这两个引脚的命名取决于所选的视角,可能会有歧义。例如,
虽然 ESP 可能在引脚 A 上发送(TX)并在引脚 B 上接收(RX)数据,但从另一设备的角度来看,这两个引脚是交换的(即它在引脚 B 上发送并在引脚 A 上接收)。所以如果立即不起作用,您可能需要尝试交换这两个引脚。
此外,每个 UART 总线可以以不同的速度(波特率)运行,所以 ESPHome 需要知道使用 baud_rate 选项以什么速度接收/发送数据。两个常见的波特率是 9600 和 115200。
在某些情况下,只有 TX 或 RX 存在,因为另一端的设备只接受数据或只发送数据。
UART 组件可以用作 数据包传输组件 的平台,使传感器数据能够直接从一个 ESPHome 节点通过 UART 总线发送到另一个节点。使用 RS485 时,这可以在多点配置下运行。
NOTE
在 ESP32 上,此组件使用硬件 UART 单元,因此非常准确。但在 ESP8266 上, ESPHome 必须使用软件实现,因为除了用于日志记录的硬件 UART 单元外没有其他可用的硬件 UART 单元。因此,ESP8266 上的 UART 数据可能会有偶尔的数据故障,特别是在较高波特率下。
NOTE
从 ESPHome 2021.8 开始,ESP8266SoftwareSerial UART write_byte 函数的奇偶校验位已修复为对发送的数据正确。如果您使用软件 UART 且有明确检查奇偶校验的设备,这可能会导致意外问题。您很可能需要在 YAML 中翻转 parity 标志。
NOTE
主机平台的 UART 实现不使用 TX 和 RX 引脚,而是使用端口名称。
# 示例配置项uart: tx_pin: GPIOXX rx_pin: GPIOXX baud_rate: 9600-
baud_rate (Required, int): UART 总线的波特率。
-
tx_pin (Optional, Pin): 从 ESP 角度发送数据的引脚。使用完整引脚 模式并设置
inverted: true以反转逻辑电平。主机平台不支持。 -
rx_pin (Optional, Pin): 从 ESP 角度接收数据的引脚。使用完整引脚 模式并设置
inverted: true以反转逻辑电平。主机平台不支持。 -
flow_control_pin (Optional, Pin): 仅限 ESP32。用于硬件 RS485 流控制的引脚。 使用此设置可启用半双工模式。使用完整引脚模式并设置
inverted: true以反转逻辑电平。 -
port (Optional, string): 仅限主机平台。要使用的端口的 Unix 风格名称。
-
rx_buffer_size (Optional, int): 用于接收 UART 消息的缓冲区大小。如果您使用的 集成需要从 UART 读取大负载,请增加此值。默认为
256。 -
rx_full_threshold (Optional, int): 仅限 ESP32。接收到此字节数后,数据变得可供处理。 默认值在编译时计算,大约为十毫秒(9600 波特下约 8 字节,115200 波特下约 114 字节)。
-
rx_timeout (Optional, int): 仅限 ESP32。此值指定用于确定超时持续时间的字节数。超时持续时间基于接收此字节数所需的时间量。换句话说,对于给定的值和波特率,波特率加倍将使超时持续时间减半。超时过后,数据变得可供处理。默认为
2。 -
data_bits (Optional, int): UART 总线上使用的数据位数。选项:5 到 8。默认为 8。
-
parity (Optional): UART 总线上使用的奇偶校验。选项:
NONE、EVEN、ODD。默认为NONE。 -
stop_bits (Optional, int): 要发送的停止位数。选项:1、2。默认为 1。
-
id (Optional, ID): 如果需要多个 UART 集线器,手动为此 UART 集线器指定 ID。
-
debug (Optional, mapping): 用于调试 UART 集线器上通信的选项,请参阅 调试。
硬件 UART
Section titled “硬件 UART”在可能的情况下,ESPHome 将使用 ESP8266 上的硬件 UART 单元进行快速准确的通信。 当所有硬件 UART 都被占用时,ESPHome 将回退到软件实现,该实现在较高波特率下可能不准确。
UART0(默认)被日志组件使用,使用 tx_pin: GPIO1 和
rx_pin: GPIO3。如果您配置的 UART 与这些引脚重叠,您可以与
日志记录器共享硬件,并将其他硬件留给其他用途。如果您已将日志记录器配置为使用不同的硬件 UART,用于硬件共享的引脚会相应更改。
原始 ESP32 有三个 UART。ESP32 变体(ESP32-C3、ESP32-S2 等)可能有不同数量的 UART (通常在两到六个之间)。任何 GPIO 引脚对都可以使用,只要它们支持正确的输出/输入模式。
ESP8266 有两个 UART;其中第二个仅支持 TX。只有有限的引脚集可以使用。UART0 可以使用 tx_pin: GPIO1 和 rx_pin: GPIO3,或 tx_pin: GPIO15 和 rx_pin: GPIO13。UART1 必须使用 tx_pin: GPIO2。任何其他引脚组合将导致使用软件 UART。
NOTE
软件 UART 仅在 ESP8266 上可用。在 ESP32 及其变体上不可用。
uart.write 动作
Section titled “uart.write 动作”此 动作 向给定的 UART 总线发送定义的 UART 信号。
on_...: - uart.write: 'Hello World'
# 对于转义字符,必须使用双引号! - uart.write: "Hello World\r\n"
# 原始数据 - uart.write: [0x00, 0x20, 0x42]
# 使用模板,返回类型是 std::vector<uint8_t> - uart.write: !lambda return {0x00, 0x20, 0x42};
# 如果您需要指定 uart id - uart.write: id: my_second_uart data: 'other data'如果您需要了解通过 UART 总线发送和/或接收的通信,可以使用调试功能。
# 示例配置项uart: baud_rate: 115200 debug: direction: BOTH dummy_receiver: false after: delimiter: "\n" sequence: - lambda: UARTDebug::log_string(direction, bytes);
# 最小配置示例,默认记录十六进制字符串uart: baud_rate: 9600 debug:-
direction (Optional, enum): 要调试的通信方向,可选值之一:“RX”(接收,传入)、 “TX”(发送,传出)或 “BOTH”。默认为 “BOTH”。
-
dummy_receiver (Optional, boolean): 是否启用虚拟接收器功能。调试器 只会累积实际被 UART 设备组件读取或发送的字节。当您想调试所有传入通信, 而尚未为 UART 总线配置 UART 设备组件时,此功能很有用。这对开发者特别有用。通常您会希望保持此选项禁用。默认为 false。
-
after (Optional, mapping): 调试器累积通信字节。此选项定义何时 触发发布累积的字节。可能的选项有:
-
bytes (Optional, int): 累积指定数量的字节后触发。默认为 150。
-
timeout (Optional, Time): 在指定的超时时间内没有看到通信, 而已累积一个或多个字节时触发。默认为 100ms。
-
delimiter (Optional, string 或字节列表): 在通信中检测到指定的字节序列后 触发。
-
-
sequence (Optional, Action): 用于发布调试数据的动作。 默认为以十六进制格式记录字节的动作。动作可以使用以下变量:
- direction:
uart::UART_DIRECTION_RX或uart::UART_DIRECTION_TX - bytes: 包含累积字节的
std::vector<uint8_t>
日志记录辅助函数
提供了辅助函数,使以各种格式记录调试数据变得容易:
-
UARTDebug::log_hex(direction, bytes, char separator) 将字节记录为十六进制值,用提供的分隔符字符分隔。
-
UARTDebug::log_string(direction, bytes) 将字节记录为字符串值,转义不可打印字符。
-
UARTDebug::log_int(direction, bytes, char separator) 将字节记录为整数值,用提供的分隔符字符分隔。
-
UARTDebug::log_binary(direction, bytes, char separator) 将字节记录为
<binary> (<hex>)值, 用提供的分隔符字符分隔。
日志缓冲区大小
请注意,
logger组件默认使用 512 字节的有限缓冲区大小。如果 UART 调试器日志行变得太长,您会注意到它们在日志输出中被截断。在这种情况下,要么确保调试器每行日志输出较少的数据(例如,通过将
after.bytes选项设置为较低的值),要么使用日志记录器的tx_buffer_size选项增加日志缓冲区大小。 - direction:
在某些情况下,您可能需要在运行时调整 UART 参数以提高通信效率 并适应不同的操作条件。ESPHome 通过 lambda 调用实现了这一点。 以下是读取当前设置和动态修改它们的方法:
- 读取当前设置: 使用这些只读属性访问 UART 的当前配置:
// RX 缓冲区大小 id(my_uart).get_rx_buffer_size(); // RX FIFO 满阈值 id(my_uart).get_rx_full_threshold(); // RX 超时 id(my_uart).get_rx_timeout(); // 停止位 id(my_uart).get_stop_bits(); // 数据位 id(my_uart).get_data_bits(); // 奇偶校验 id(my_uart).get_parity(); // 波特率 id(my_uart).get_baud_rate();- 在运行时修改设置: 您可以在运行时更改某些 UART 参数。
设置新值后,调用
load_settings()(仅限 ESP)以应用这些更改:
select: - id: change_baud_rate name: 波特率 platform: template options: - "2400" - "9600" - "38400" - "57600" - "115200" - "256000" - "512000" - "921600" initial_option: "115200" optimistic: true restore_value: True internal: false entity_category: config icon: mdi:swap-horizontal set_action: - lambda: |- id(my_uart).flush(); uint32_t new_baud_rate = stoi(x); ESP_LOGD("change_baud_rate", "将波特率从 %i 更改为 %i",id(my_uart).get_baud_rate(), new_baud_rate); if (id(my_uart).get_baud_rate() != new_baud_rate) { id(my_uart).set_baud_rate(new_baud_rate); id(my_uart).load_settings(); }可用于运行时更改的方法:
// 设置 TX/RX/流控制引脚 id(my_uart).set_tx_pin(InternalGPIOPin *tx_pin); id(my_uart).set_rx_pin(InternalGPIOPin *rx_pin); id(my_uart).set_flow_control_pin(InternalGPIOPin *flow_control_pin); // RX 缓冲区大小 id(my_uart).set_rx_buffer_size(size_t rx_buffer_size); // RX FIFO 满阈值(以字节为单位) id(my_uart).set_rx_full_threshold(size_t rx_full_threshold); // RX FIFO 满阈值(以时间单位) id(my_uart).set_rx_full_threshold_ms(uint8_t time); // RX 超时 id(my_uart).set_rx_timeout(size_t rx_timeout); // 停止位 id(my_uart).set_stop_bits(uint8_t stop_bits); // 数据位 id(my_uart).set_data_bits(uint8_t data_bits); // 奇偶校验 id(my_uart).set_parity(UARTParityOptions parity); // 波特率 id(my_uart).set_baud_rate(uint32_t baud_rate);这种灵活性允许动态适应不同的通信要求,增强您的 ESPHome 设置的多功能性。
主机平台上的 UART 组件
Section titled “主机平台上的 UART 组件”由于主机平台没有物理 UART 引脚,UART 组件使用 Unix 风格的端口实现。
您可以使用端口名称来指定要使用的端口,而不是使用引脚。此实现还支持具有 require_tx 和 require_rx 选项的组件,如 smt100 等。
# 主机平台的示例配置项uart: baud_rate: 9600 port: "/dev/ttyUSB0"