From 441ec35d9fd678f482d7c29d42d78dc421e9f6c6 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 7 Feb 2026 00:07:44 +0100 Subject: [PATCH] [seeed_mr24hpc1/mr60fda2/mr60bha2] Batch UART reads to reduce per-loop overhead Replace byte-at-a-time read_byte() calls with batched read_array() in all three Seeed MR sensor components. Each read_byte() internally chains through read_array(data, 1) -> check_read_timeout_(1) -> available(), resulting in ~3 UART driver calls per byte. Batching into a 64-byte stack buffer reduces this to ~3 calls per loop iteration regardless of how many bytes are available. --- .../seeed_mr24hpc1/seeed_mr24hpc1.cpp | 19 ++++++++++---- .../seeed_mr60bha2/seeed_mr60bha2.cpp | 25 +++++++++++++------ .../seeed_mr60fda2/seeed_mr60fda2.cpp | 21 ++++++++++++---- 3 files changed, 48 insertions(+), 17 deletions(-) diff --git a/esphome/components/seeed_mr24hpc1/seeed_mr24hpc1.cpp b/esphome/components/seeed_mr24hpc1/seeed_mr24hpc1.cpp index 08d83f9390..949c220c3d 100644 --- a/esphome/components/seeed_mr24hpc1/seeed_mr24hpc1.cpp +++ b/esphome/components/seeed_mr24hpc1/seeed_mr24hpc1.cpp @@ -106,12 +106,21 @@ void MR24HPC1Component::update_() { // main loop void MR24HPC1Component::loop() { - uint8_t byte; + int avail = this->available(); + if (avail > 0) { + // Read all available bytes in batches to reduce UART call overhead. + uint8_t buf[64]; + while (avail > 0) { + size_t to_read = std::min(static_cast(avail), sizeof(buf)); + if (!this->read_array(buf, to_read)) { + break; + } + avail -= to_read; - // Is there data on the serial port - while (this->available()) { - this->read_byte(&byte); - this->r24_split_data_frame_(byte); // split data frame + for (size_t i = 0; i < to_read; i++) { + this->r24_split_data_frame_(buf[i]); // split data frame + } + } } if ((this->s_output_info_switch_flag_ == OUTPUT_SWTICH_OFF) && diff --git a/esphome/components/seeed_mr60bha2/seeed_mr60bha2.cpp b/esphome/components/seeed_mr60bha2/seeed_mr60bha2.cpp index b9ce1f9151..8cbf3e2e29 100644 --- a/esphome/components/seeed_mr60bha2/seeed_mr60bha2.cpp +++ b/esphome/components/seeed_mr60bha2/seeed_mr60bha2.cpp @@ -30,14 +30,25 @@ void MR60BHA2Component::dump_config() { // main loop void MR60BHA2Component::loop() { - uint8_t byte; + int avail = this->available(); + if (avail == 0) { + return; + } - // Is there data on the serial port - while (this->available()) { - this->read_byte(&byte); - this->rx_message_.push_back(byte); - if (!this->validate_message_()) { - this->rx_message_.clear(); + // Read all available bytes in batches to reduce UART call overhead. + uint8_t buf[64]; + while (avail > 0) { + size_t to_read = std::min(static_cast(avail), sizeof(buf)); + if (!this->read_array(buf, to_read)) { + break; + } + avail -= to_read; + + for (size_t i = 0; i < to_read; i++) { + this->rx_message_.push_back(buf[i]); + if (!this->validate_message_()) { + this->rx_message_.clear(); + } } } } diff --git a/esphome/components/seeed_mr60fda2/seeed_mr60fda2.cpp b/esphome/components/seeed_mr60fda2/seeed_mr60fda2.cpp index b5b5b4d05a..259e60119d 100644 --- a/esphome/components/seeed_mr60fda2/seeed_mr60fda2.cpp +++ b/esphome/components/seeed_mr60fda2/seeed_mr60fda2.cpp @@ -49,12 +49,23 @@ void MR60FDA2Component::setup() { // main loop void MR60FDA2Component::loop() { - uint8_t byte; + int avail = this->available(); + if (avail == 0) { + return; + } - // Is there data on the serial port - while (this->available()) { - this->read_byte(&byte); - this->split_frame_(byte); // split data frame + // Read all available bytes in batches to reduce UART call overhead. + uint8_t buf[64]; + while (avail > 0) { + size_t to_read = std::min(static_cast(avail), sizeof(buf)); + if (!this->read_array(buf, to_read)) { + break; + } + avail -= to_read; + + for (size_t i = 0; i < to_read; i++) { + this->split_frame_(buf[i]); // split data frame + } } }