supla-device
Loading...
Searching...
No Matches
SGP41.h
1/*
2 Copyright (C) malarz
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17*/
18
19#ifndef SRC_SUPLA_SENSOR_SGP41_H_
20#define SRC_SUPLA_SENSOR_SGP41_H_
21
22// Dependency: Sensirion I2C SGP41 Arduino Library
23// - use library manager to install it
24// https://github.com/Sensirion/arduino-i2c-sgp41
25
26#include "SensirionI2CSgp41.h"
27
28#include <supla/sensor/therm_hygro_meter.h>
29#include <supla/sensor/general_purpose_measurement.h>
30
31namespace Supla {
32namespace Sensor {
33class SGP41 : public Element {
34 public:
35 explicit SGP41(ThermHygroMeter *ptr = nullptr) {
36 th = ptr;
37 vocchannel = new GeneralPurposeMeasurement();
38 vocchannel->setDefaultUnitAfterValue("");
39 vocchannel->setInitialCaption("VOC index");
40 vocchannel->getChannel()->setDefaultIcon(8);
41 vocchannel->setDefaultValuePrecision(1);
42
43 noxchannel = new GeneralPurposeMeasurement();
44 noxchannel->setDefaultUnitAfterValue("");
45 noxchannel->setInitialCaption("NOx index");
46 noxchannel->getChannel()->setDefaultIcon(8);
47 noxchannel->setDefaultValuePrecision(1);
48 }
49
50 void onInit() override {
51 sgp.begin(Wire);
52 }
53
54 GeneralPurposeMeasurement* getVOCchannel() {
55 return vocchannel;
56 }
57
58 GeneralPurposeMeasurement* getNOXchannel() {
59 return noxchannel;
60 }
61
62 void iterateAlways() override {
63 // every 1 sec read from device
64 if (millis() - lastReadTime > 1000) {
65 readValuesFromDevice();
66 lastReadTime = millis();
67 }
68 }
69
70 private:
71 void readValuesFromDevice() {
72 uint16_t error;
73 float temperature = TEMPERATURE_NOT_AVAILABLE;
74 float humidity = HUMIDITY_NOT_AVAILABLE;
75 if (th != nullptr) {
76 temperature = th->getChannel()->getLastTemperature();
77 humidity = th->getChannel()->getValueDoubleSecond();
78 }
79 uint16_t srawVoc = 0;
80 uint16_t srawNox = 0;
81
82 if (temperature != TEMPERATURE_NOT_AVAILABLE) {
83 compensationT = static_cast<uint16_t>((temperature + 45) * 65535 / 175);
84 } else {
85 compensationT = defaultCompenstaionT;
86 }
87
88 if (humidity != HUMIDITY_NOT_AVAILABLE) {
89 compensationRh = static_cast<uint16_t>(humidity * 65535 / 100);
90 } else {
91 compensationRh = defaultCompenstaionRh;
92 }
93
94 if (skipFirstReadingsCounter > 0) {
95 error = sgp.executeConditioning(compensationRh, compensationT, srawVoc);
96 skipFirstReadingsCounter--;
97 } else {
98 error = sgp.measureRawSignals(compensationRh, compensationT, srawVoc,
99 srawNox);
100 }
101
102 if (error) {
103 retryCount++;
104 if (retryCount > 10) {
105 vocchannel->setValue(NAN);
106 noxchannel->setValue(NAN);
107 }
108 } else {
109 retryCount = 0;
110 vocchannel->setValue(srawVoc);
111 noxchannel->setValue(srawNox);
112 }
113 }
114
115 protected:
116 uint16_t defaultCompenstaionRh = 0x8000; // in ticks as defined by SGP41
117 uint16_t defaultCompenstaionT = 0x6666; // in ticks as defined by SGP41
118 uint16_t compensationRh = 0; // in ticks as defined by SGP41
119 uint16_t compensationT = 0; // in ticks as defined by SGP41
120 int8_t retryCount = 0;
121 ::SensirionI2CSgp41 sgp;
122 GeneralPurposeMeasurement *vocchannel = nullptr;
123 GeneralPurposeMeasurement *noxchannel = nullptr;
124 ThermHygroMeter *th = nullptr;
125 uint32_t lastReadTime = 0;
126 int skipFirstReadingsCounter = 10;
127};
128
129}; // namespace Sensor
130}; // namespace Supla
131
132#endif // SRC_SUPLA_SENSOR_SGP41_H_
Definition general_purpose_measurement.h:26
Definition general_purpose_measurement.h:26
void iterateAlways() override
Method called on each SuplaDevice iteration.
Definition SGP41.h:62
void onInit() override
Third method called on element in SuplaDevice.begin()
Definition SGP41.h:50
Definition therm_hygro_meter.h:29