1
0
mirror of https://github.com/esphome/esphome.git synced 2026-02-09 09:11:52 +00:00

Compare commits

..

1 Commits

Author SHA1 Message Date
J. Nick Koston
c77d70c093 [tuya] Batch UART reads to reduce per-loop overhead
Replace byte-at-a-time read_byte() calls with batched read_array()
in loop(). 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.
2026-02-07 00:17:26 +01:00
2 changed files with 38 additions and 45 deletions

View File

@@ -13,12 +13,9 @@ void Pipsolar::setup() {
}
void Pipsolar::empty_uart_buffer_() {
uint8_t buf[64];
int avail;
while ((avail = this->available()) > 0) {
if (!this->read_array(buf, std::min(static_cast<size_t>(avail), sizeof(buf)))) {
break;
}
uint8_t byte;
while (this->available()) {
this->read_byte(&byte);
}
}
@@ -97,47 +94,32 @@ void Pipsolar::loop() {
}
if (this->state_ == STATE_COMMAND || this->state_ == STATE_POLL) {
int avail = this->available();
while (avail > 0) {
uint8_t buf[64];
size_t to_read = std::min(static_cast<size_t>(avail), sizeof(buf));
if (!this->read_array(buf, to_read)) {
while (this->available()) {
uint8_t byte;
this->read_byte(&byte);
// make sure data and null terminator fit in buffer
if (this->read_pos_ >= PIPSOLAR_READ_BUFFER_LENGTH - 1) {
this->read_pos_ = 0;
this->empty_uart_buffer_();
ESP_LOGW(TAG, "response data too long, discarding.");
break;
}
avail -= to_read;
bool done = false;
for (size_t i = 0; i < to_read; i++) {
uint8_t byte = buf[i];
this->read_buffer_[this->read_pos_] = byte;
this->read_pos_++;
// make sure data and null terminator fit in buffer
if (this->read_pos_ >= PIPSOLAR_READ_BUFFER_LENGTH - 1) {
this->read_pos_ = 0;
this->empty_uart_buffer_();
ESP_LOGW(TAG, "response data too long, discarding.");
done = true;
break;
// end of answer
if (byte == 0x0D) {
this->read_buffer_[this->read_pos_] = 0;
this->empty_uart_buffer_();
if (this->state_ == STATE_POLL) {
this->state_ = STATE_POLL_COMPLETE;
}
this->read_buffer_[this->read_pos_] = byte;
this->read_pos_++;
// end of answer
if (byte == 0x0D) {
this->read_buffer_[this->read_pos_] = 0;
this->empty_uart_buffer_();
if (this->state_ == STATE_POLL) {
this->state_ = STATE_POLL_COMPLETE;
}
if (this->state_ == STATE_COMMAND) {
this->state_ = STATE_COMMAND_COMPLETE;
}
done = true;
break;
if (this->state_ == STATE_COMMAND) {
this->state_ = STATE_COMMAND_COMPLETE;
}
}
if (done) {
break;
}
}
} // available
}
if (this->state_ == STATE_COMMAND) {
if (millis() - this->command_start_millis_ > esphome::pipsolar::Pipsolar::COMMAND_TIMEOUT) {

View File

@@ -31,10 +31,21 @@ void Tuya::setup() {
}
void Tuya::loop() {
while (this->available()) {
uint8_t c;
this->read_byte(&c);
this->handle_char_(c);
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<size_t>(avail), sizeof(buf));
if (!this->read_array(buf, to_read)) {
break;
}
avail -= to_read;
for (size_t i = 0; i < to_read; i++) {
this->handle_char_(buf[i]);
}
}
}
process_command_queue_();
}