* Sample from SGP40 sensor at the appropriate interval

The spg40 sensor must be sampled at 1Hz for the VOC index algorithm
to work correctly. This commit introduces a on device timer to
sample correctly seperately from updating the public state of the
component.

* Add missing configuration values for SGP40

The SGP40 component was not printing all of it's configuration in
dump_config, add in the missing store_baseline value.

* Address review comments

* Format according to clang-tidy

* Attempt 2 at clang tidy
This commit is contained in:
Nate Lust 2021-10-10 04:33:04 -04:00 committed by GitHub
parent c092d92d45
commit 92b85f98e8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 7 deletions

View file

@ -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_() {
@ -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();
}
@ -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:

View file

@ -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; }
@ -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;