diff --git a/esphome/components/t6615/t6615.cpp b/esphome/components/t6615/t6615.cpp index 09ff61827c..c139c56ce4 100644 --- a/esphome/components/t6615/t6615.cpp +++ b/esphome/components/t6615/t6615.cpp @@ -6,7 +6,7 @@ namespace t6615 { static const char *const TAG = "t6615"; -static const uint8_t T6615_RESPONSE_BUFFER_LENGTH = 32; +static const uint32_t T6615_TIMEOUT = 1000; static const uint8_t T6615_MAGIC = 0xFF; static const uint8_t T6615_ADDR_HOST = 0xFA; static const uint8_t T6615_ADDR_SENSOR = 0xFE; @@ -19,31 +19,49 @@ static const uint8_t T6615_COMMAND_ENABLE_ABC[] = {0xB7, 0x01}; static const uint8_t T6615_COMMAND_DISABLE_ABC[] = {0xB7, 0x02}; static const uint8_t T6615_COMMAND_SET_ELEVATION[] = {0x03, 0x0F}; -void T6615Component::loop() { - if (!this->available()) - return; +void T6615Component::send_ppm_command_() { + this->command_time_ = millis(); + this->command_ = T6615Command::GET_PPM; + this->write_byte(T6615_MAGIC); + this->write_byte(T6615_ADDR_SENSOR); + this->write_byte(sizeof(T6615_COMMAND_GET_PPM)); + this->write_array(T6615_COMMAND_GET_PPM, sizeof(T6615_COMMAND_GET_PPM)); +} - // Read header - uint8_t header[3]; - this->read_array(header, 3); - if (header[0] != T6615_MAGIC || header[1] != T6615_ADDR_HOST) { - ESP_LOGW(TAG, "Reading data from T6615 failed!"); - while (this->available()) - this->read(); // Clear the incoming buffer - this->status_set_warning(); +void T6615Component::loop() { + if (this->available() < 5) { + if (this->command_ == T6615Command::GET_PPM && millis() - this->command_time_ > T6615_TIMEOUT) { + /* command got eaten, clear the buffer and fire another */ + while (this->available()) + this->read(); + this->send_ppm_command_(); + } return; } - // Read body - uint8_t length = header[2]; - uint8_t response[T6615_RESPONSE_BUFFER_LENGTH]; - this->read_array(response, length); + uint8_t response_buffer[6]; + + /* by the time we get here, we know we have at least five bytes in the buffer */ + this->read_array(response_buffer, 5); + + // Read header + if (response_buffer[0] != T6615_MAGIC || response_buffer[1] != T6615_ADDR_HOST) { + ESP_LOGW(TAG, "Got bad data from T6615! Magic was %02X and address was %02X", response_buffer[0], + response_buffer[1]); + /* make sure the buffer is empty */ + while (this->available()) + this->read(); + /* try again to read the sensor */ + this->send_ppm_command_(); + this->status_set_warning(); + return; + } this->status_clear_warning(); switch (this->command_) { case T6615Command::GET_PPM: { - const uint16_t ppm = encode_uint16(response[0], response[1]); + const uint16_t ppm = encode_uint16(response_buffer[3], response_buffer[4]); ESP_LOGD(TAG, "T6615 Received CO₂=%uppm", ppm); this->co2_sensor_->publish_state(ppm); break; @@ -51,23 +69,19 @@ void T6615Component::loop() { default: break; } - + this->command_time_ = 0; this->command_ = T6615Command::NONE; } void T6615Component::update() { this->query_ppm_(); } void T6615Component::query_ppm_() { - if (this->co2_sensor_ == nullptr || this->command_ != T6615Command::NONE) { + if (this->co2_sensor_ == nullptr || + (this->command_ != T6615Command::NONE && millis() - this->command_time_ < T6615_TIMEOUT)) { return; } - this->command_ = T6615Command::GET_PPM; - - this->write_byte(T6615_MAGIC); - this->write_byte(T6615_ADDR_SENSOR); - this->write_byte(sizeof(T6615_COMMAND_GET_PPM)); - this->write_array(T6615_COMMAND_GET_PPM, sizeof(T6615_COMMAND_GET_PPM)); + this->send_ppm_command_(); } float T6615Component::get_setup_priority() const { return setup_priority::DATA; } diff --git a/esphome/components/t6615/t6615.h b/esphome/components/t6615/t6615.h index a7da3b4cf6..a075685023 100644 --- a/esphome/components/t6615/t6615.h +++ b/esphome/components/t6615/t6615.h @@ -32,8 +32,10 @@ class T6615Component : public PollingComponent, public uart::UARTDevice { protected: void query_ppm_(); + void send_ppm_command_(); T6615Command command_ = T6615Command::NONE; + unsigned long command_time_ = 0; sensor::Sensor *co2_sensor_{nullptr}; };