Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sgp40 fix #2462

Merged
merged 5 commits into from Oct 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
35 changes: 28 additions & 7 deletions esphome/components/sgp40/sgp40.cpp
Expand Up @@ -77,6 +77,20 @@ void SGP40Component::setup() {
}

this->self_test_();

/* The official spec for this sensor at https://docs.rs-online.com/1956/A700000007055193.pdf
indicates this sensor should be driven at 1Hz. Comments from the developers at:
https://github.com/Sensirion/embedded-sgp/issues/136 indicate the algorithm should be a bit
resilient to slight timing variations so the software timer should be accurate enough for
this.

This block starts sampling from the sensor at 1Hz, and is done seperately from the call
to the update method. This seperation is to support getting accurate measurements but
limit the amount of communication done over wifi for power consumption or to keep the
number of records reported from being overwhelming.
*/
ESP_LOGD(TAG, "Component requires sampling of 1Hz, setting up background sampler");
this->set_interval(1000, [this]() { this->update_voc_index(); });
}

void SGP40Component::self_test_() {
Expand Down Expand Up @@ -224,21 +238,26 @@ uint8_t SGP40Component::generate_crc_(const uint8_t *data, uint8_t datalen) {
return crc;
}

void SGP40Component::update() {
this->seconds_since_last_store_ += this->update_interval_ / 1000;

uint32_t voc_index = this->measure_voc_index_();
void SGP40Component::update_voc_index() {
this->seconds_since_last_store_ += 1;

this->voc_index_ = this->measure_voc_index_();
if (this->samples_read_ < this->samples_to_stabalize_) {
this->samples_read_++;
ESP_LOGD(TAG, "Sensor has not collected enough samples yet. (%d/%d) VOC index is: %u", this->samples_read_,
this->samples_to_stabalize_, voc_index);
this->samples_to_stabalize_, this->voc_index_);
return;
}
}

void SGP40Component::update() {
if (this->samples_read_ < this->samples_to_stabalize_) {
return;
}

if (voc_index != UINT16_MAX) {
if (this->voc_index_ != UINT16_MAX) {
this->status_clear_warning();
this->publish_state(voc_index);
this->publish_state(this->voc_index_);
} else {
this->status_set_warning();
}
Expand All @@ -247,6 +266,8 @@ void SGP40Component::update() {
void SGP40Component::dump_config() {
ESP_LOGCONFIG(TAG, "SGP40:");
LOG_I2C_DEVICE(this);
ESP_LOGCONFIG(TAG, " store_baseline: %d", this->store_baseline_);

if (this->is_failed()) {
switch (this->error_code_) {
case COMMUNICATION_FAILED:
Expand Down
2 changes: 2 additions & 0 deletions esphome/components/sgp40/sgp40.h
Expand Up @@ -46,6 +46,7 @@ class SGP40Component : public PollingComponent, public sensor::Sensor, public i2

void setup() override;
void update() override;
void update_voc_index();
void dump_config() override;
float get_setup_priority() const override { return setup_priority::DATA; }
void set_store_baseline(bool store_baseline) { store_baseline_ = store_baseline; }
Expand All @@ -72,6 +73,7 @@ class SGP40Component : public PollingComponent, public sensor::Sensor, public i2
bool store_baseline_;
int32_t state0_;
int32_t state1_;
int32_t voc_index_ = 0;
uint8_t samples_read_ = 0;
uint8_t samples_to_stabalize_ = static_cast<int8_t>(VOC_ALGORITHM_INITIAL_BLACKOUT) * 2;

Expand Down