From d4f28dd17b9f22c4bceaf309981f5c30e72d71f4 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Sun, 5 May 2019 21:58:01 +0200 Subject: [PATCH] mhz19: cleanup uart RX buffer before sending command When sensor is connected to hardware uart, sometimes on boot uart's RX buffer contains several bytes of junk. Workaround it by draining all of it before sending command. Also turn on cleanup logic only if problem is detected (i.e. when reply from sensor doesn't look correct. Signed-off-by: Igor Mammedov --- esphome/components/mhz19/mhz19.cpp | 47 +++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/esphome/components/mhz19/mhz19.cpp b/esphome/components/mhz19/mhz19.cpp index 3b06ea40c9..97983fe737 100644 --- a/esphome/components/mhz19/mhz19.cpp +++ b/esphome/components/mhz19/mhz19.cpp @@ -52,23 +52,42 @@ void MHZ19Component::update() { } bool MHZ19Component::mhz19_write_command_(const uint8_t *command, uint8_t *response) { - ESP_LOGD(TAG, "cmd [%s]", dump_data_buf(command)); - this->write_array(command, MHZ19_PDU_LENGTH); - this->flush(); + bool ret; + int rx_error = 0; - if (response == nullptr) - return true; + do { + ESP_LOGD(TAG, "cmd [%s]", dump_data_buf(command)); + this->write_array(command, MHZ19_PDU_LENGTH); + this->flush(); - bool ret = this->read_array(response, MHZ19_PDU_LENGTH); - ESP_LOGD(TAG, "resp [%s]", dump_data_buf(response)); + if (response == nullptr) + return true; - uint8_t checksum = mhz19_checksum(response); - if (checksum != response[8]) { - ESP_LOGW(TAG, "MHZ19 Checksum doesn't match: 0x%02X!=0x%02X [%s]", - response[8], checksum, dump_data_buf(response)); - this->status_set_warning(); - return false; - } + memset(response, 0, MHZ19_PDU_LENGTH); + ret = this->read_array(response, MHZ19_PDU_LENGTH); + ESP_LOGD(TAG, "resp [%s]", dump_data_buf(response)); + + uint8_t checksum = mhz19_checksum(response); + if (checksum != response[8]) { + ESP_LOGW(TAG, "MHZ19 Checksum doesn't match: 0x%02X!=0x%02X [%s]", + response[8], checksum, dump_data_buf(response)); + + /* + * UART0 in NodeMCU v2, sometimes on boot has junk in RX buffer, + * check for it and drain all of it before sending commands to sensor + */ + this->drain(); + ret = false; + if (++rx_error > 2) { + this->status_set_warning(); + /* give up trying to recover, hope that it will be fine next update cycle */ + rx_error = 0; + } + delay(100); + } else { + rx_error = 0; + } + } while (rx_error); return ret; }