supla-device
Loading...
Searching...
No Matches
SGP41.h
1// SPDX-FileCopyrightText: malarz
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#ifndef SRC_SUPLA_SENSOR_SGP41_H_
5#define SRC_SUPLA_SENSOR_SGP41_H_
6
7// Dependency: Sensirion I2C SGP41 Arduino Library
8// - use library manager to install it
9// https://github.com/Sensirion/arduino-i2c-sgp41
10
11#include "SensirionI2CSgp41.h"
12
13#include <supla/sensor/therm_hygro_meter.h>
14#include <supla/sensor/general_purpose_measurement.h>
15
16namespace Supla {
17namespace Sensor {
18class SGP41 : public Element {
19 public:
20 explicit SGP41(ThermHygroMeter *ptr = nullptr) {
21 th = ptr;
22 vocchannel = new GeneralPurposeMeasurement();
23 vocchannel->setDefaultUnitAfterValue("");
24 vocchannel->setInitialCaption("VOC index");
25 vocchannel->getChannel()->setDefaultIcon(8);
26 vocchannel->setDefaultValuePrecision(1);
27
28 noxchannel = new GeneralPurposeMeasurement();
29 noxchannel->setDefaultUnitAfterValue("");
30 noxchannel->setInitialCaption("NOx index");
31 noxchannel->getChannel()->setDefaultIcon(8);
32 noxchannel->setDefaultValuePrecision(1);
33 }
34
35 void onInit() override {
36 sgp.begin(Wire);
37 }
38
39 GeneralPurposeMeasurement* getVOCchannel() {
40 return vocchannel;
41 }
42
43 GeneralPurposeMeasurement* getNOXchannel() {
44 return noxchannel;
45 }
46
47 void iterateAlways() override {
48 // every 1 sec read from device
49 if (millis() - lastReadTime > 1000) {
50 readValuesFromDevice();
51 lastReadTime = millis();
52 }
53 }
54
55 private:
56 void readValuesFromDevice() {
57 uint16_t error;
58 float temperature = TEMPERATURE_NOT_AVAILABLE;
59 float humidity = HUMIDITY_NOT_AVAILABLE;
60 if (th != nullptr) {
61 temperature = th->getChannel()->getLastTemperature();
62 humidity = th->getChannel()->getValueDoubleSecond();
63 }
64 uint16_t srawVoc = 0;
65 uint16_t srawNox = 0;
66
67 if (temperature >= -45 && temperature <= 130) {
68 compensationT = static_cast<uint16_t>((temperature + 45) * 65535 / 175);
69 } else {
70 compensationT = defaultCompenstaionT;
71 }
72
73 if (humidity >= 0 && humidity <= 100) {
74 compensationRh = static_cast<uint16_t>(humidity * 65535 / 100);
75 } else {
76 compensationRh = defaultCompenstaionRh;
77 }
78
79 if (skipFirstReadingsCounter > 0) {
80 error = sgp.executeConditioning(compensationRh, compensationT, srawVoc);
81 skipFirstReadingsCounter--;
82 } else {
83 error = sgp.measureRawSignals(compensationRh, compensationT, srawVoc,
84 srawNox);
85 }
86
87 if (error) {
88 if (retryCount <= 10) {
89 retryCount++;
90 }
91 if (retryCount > 10) {
92 vocchannel->setValue(NAN);
93 noxchannel->setValue(NAN);
94 }
95 } else {
96 retryCount = 0;
97 vocchannel->setValue(srawVoc);
98 noxchannel->setValue(srawNox);
99 }
100 }
101
102 protected:
103 uint16_t defaultCompenstaionRh = 0x8000; // in ticks as defined by SGP41
104 uint16_t defaultCompenstaionT = 0x6666; // in ticks as defined by SGP41
105 uint16_t compensationRh = 0; // in ticks as defined by SGP41
106 uint16_t compensationT = 0; // in ticks as defined by SGP41
107 int8_t retryCount = 0;
108 ::SensirionI2CSgp41 sgp;
109 GeneralPurposeMeasurement *vocchannel = nullptr;
110 GeneralPurposeMeasurement *noxchannel = nullptr;
111 ThermHygroMeter *th = nullptr;
112 uint32_t lastReadTime = 0;
113 int skipFirstReadingsCounter = 10;
114};
115
116}; // namespace Sensor
117}; // namespace Supla
118
119#endif // SRC_SUPLA_SENSOR_SGP41_H_
void setDefaultIcon(uint8_t iconId)
Sets default icon.
Definition channel.cpp:1562
Base class for all elements of SuplaDevice.
Definition element.h:27
void setInitialCaption(const char *caption, bool secondaryChannel=false)
Sets initial caption.
Definition element.cpp:390
void setDefaultUnitAfterValue(const char *unit)
Sets default unit which is displayed after value.
Definition general_purpose_channel_base.cpp:197
virtual void setValue(const double &value)
Method used to set new value for channel with driver which accepts MeasurementDriver::setValue() meth...
Definition general_purpose_channel_base.cpp:560
void setDefaultValuePrecision(uint8_t precision)
Sets default precision (number of decimal places)
Definition general_purpose_channel_base.cpp:182
Definition general_purpose_measurement.h:11
Definition SGP41.h:18
void iterateAlways() override
Method called on each SuplaDevice iteration.
Definition SGP41.h:47
void onInit() override
Third method called on element in SuplaDevice.begin()
Definition SGP41.h:35
Definition therm_hygro_meter.h:14