Skip to content

Commit 1dc39ca

Browse files
committed
I2C: per-driver fastTick call site; fix fastTick docs; SGP30/SGP40: remove averaging, cache single reads; minor doc/guard fixes
1 parent 222e45b commit 1dc39ca

File tree

4 files changed

+63
-105
lines changed

4 files changed

+63
-105
lines changed

src/components/i2c/WipperSnapper_I2C.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,12 +1347,6 @@ void WipperSnapper_Component_I2C::update() {
13471347
msgi2cResponse.which_payload =
13481348
wippersnapper_signal_v1_I2CResponse_resp_i2c_device_event_tag;
13491349

1350-
// one fast pass for all drivers every update() call
1351-
for (auto *drv : drivers) {
1352-
if (drv)
1353-
drv->fastTick();
1354-
}
1355-
13561350
long curTime;
13571351
bool sensorsReturningFalse = true;
13581352
int retries = 3;
@@ -1364,6 +1358,9 @@ void WipperSnapper_Component_I2C::update() {
13641358

13651359
std::vector<WipperSnapper_I2C_Driver *>::iterator iter, end;
13661360
for (iter = drivers.begin(), end = drivers.end(); iter != end; ++iter) {
1361+
// Per-driver fast tick (non-blocking)
1362+
(*iter)->fastTick();
1363+
13671364
// Number of events which occurred for this driver
13681365
msgi2cResponse.payload.resp_i2c_device_event.sensor_event_count = 0;
13691366

src/components/i2c/drivers/WipperSnapper_I2C_Driver.h

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class WipperSnapper_I2C_Driver {
3434
public:
3535
/*******************************************************************************/
3636
/*!
37-
@brief Instanctiates an I2C sensor.
37+
@brief Instantiates an I2C sensor.
3838
@param i2c
3939
The I2C hardware interface, default is Wire.
4040
@param sensorAddress
@@ -55,14 +55,15 @@ class WipperSnapper_I2C_Driver {
5555

5656
/*******************************************************************************/
5757
/*!
58-
@brief Per-update background hook for drivers that need faster internal
59-
sampling than the user publish interval.
60-
Default is a no-op; override in concrete drivers (e.g.,
61-
SGP30/40) to maintain required ~1 Hz reads and accumulate/condition values
62-
for later publish.
63-
@note Call site: WipperSnapper_Component_I2C::update() will invoke
64-
this once per loop for each driver. Implementations must be
65-
non-blocking (do not delay); use millis()-based timing.
58+
@brief Lightweight, per-update background hook for drivers that need
59+
more frequent internal polling than the publish interval.
60+
Default is a no-op; concrete drivers (e.g., SGP30/40) may
61+
override this to perform a single non-blocking read and cache
62+
results for later retrieval by getEvent*().
63+
@note Call site: WipperSnapper_Component_I2C::update() invokes this
64+
once per loop for each driver. Implementations must be
65+
non-blocking (do not delay); use millis()-based timing if
66+
cadence is required.
6667
*/
6768
/*******************************************************************************/
6869
virtual void fastTick() {}
@@ -1413,8 +1414,8 @@ class WipperSnapper_I2C_Driver {
14131414
long _ambientTempFPeriod = 0L; ///< The time period between reading the
14141415
///< ambient temp. (°F) sensor's value.
14151416
long _ambientTempFPeriodPrv =
1416-
PERIOD_24HRS_AGO_MILLIS; ///< The time when the ambient temp. (°F) sensor
1417-
///< was last read.
1417+
PERIOD_24HRS_AGO_MILLIS; ///< The time when the ambient temp. (°F) sensor
1418+
///< was last read.
14181419
long _objectTempFPeriod = 0L; ///< The time period between reading the object
14191420
///< temp. (°F) sensor's value.
14201421
long _objectTempFPeriodPrv =

src/components/i2c/drivers/WipperSnapper_I2C_Driver_SGP30.h

Lines changed: 35 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ class WipperSnapper_I2C_Driver_SGP30 : public WipperSnapper_I2C_Driver {
3333
*/
3434
/*******************************************************************************/
3535
~WipperSnapper_I2C_Driver_SGP30() override {
36-
// Called when a SGP30 component is deleted.
3736
if (_sgp30) {
3837
delete _sgp30;
3938
_sgp30 = nullptr;
@@ -53,74 +52,62 @@ class WipperSnapper_I2C_Driver_SGP30 : public WipperSnapper_I2C_Driver {
5352
_sgp30 = nullptr;
5453
return false;
5554
}
56-
_sgp30->IAQinit(); // start IAQ algorithm
57-
_lastFastMs = millis(); // reset fast sampler
58-
_n = _eco2Sum = _tvocSum = 0; // clear accumulators
55+
_sgp30->IAQinit(); // start IAQ algorithm
56+
_did_measure = false;
5957
return true;
6058
}
6159

6260
bool getEventECO2(sensors_event_t *senseEvent) override {
6361
if (!_sgp30)
6462
return false;
65-
if (_n > 0) {
66-
senseEvent->eCO2 = (uint16_t)(_eco2Sum / _n);
67-
_eco2Sum = 0;
68-
_tvocSum = 0;
69-
_n = 0;
70-
return true;
63+
if (!_did_measure) {
64+
_did_measure = _sgp30->IAQmeasure();
7165
}
72-
if (_sgp30->IAQmeasure()) {
73-
senseEvent->eCO2 = (uint16_t)_sgp30->eCO2;
74-
return true;
75-
}
76-
return false;
66+
if (!_did_measure)
67+
return false;
68+
69+
senseEvent->eCO2 = (uint16_t)_sgp30->eCO2;
70+
_did_measure = false; // consume cached reading
71+
return true;
7772
}
7873

7974
bool getEventTVOC(sensors_event_t *senseEvent) override {
8075
if (!_sgp30)
8176
return false;
82-
if (_n > 0) {
83-
senseEvent->tvoc = (uint16_t)(_tvocSum / _n);
84-
_eco2Sum = 0;
85-
_tvocSum = 0;
86-
_n = 0;
87-
return true;
88-
}
89-
if (_sgp30->IAQmeasure()) {
90-
senseEvent->tvoc = (uint16_t)_sgp30->TVOC;
91-
return true;
77+
if (!_did_measure) {
78+
_did_measure = _sgp30->IAQmeasure();
9279
}
93-
return false;
80+
if (!_did_measure)
81+
return false;
82+
83+
senseEvent->tvoc = (uint16_t)_sgp30->TVOC;
84+
_did_measure = false; // consume cached reading
85+
return true;
9486
}
9587

88+
/*******************************************************************************/
89+
/*!
90+
@brief Performs a lightweight background poll for the SGP30.
91+
Calls IAQmeasure() once and caches whether it succeeded.
92+
Cached values (eCO2, TVOC) are then available via getEvent*().
93+
No averaging or delay; must be non-blocking.
94+
*/
95+
/*******************************************************************************/
9696
void fastTick() override {
97+
if (!_sgp30)
98+
return;
9799
if (!iaqEnabled())
98-
return; // nothing enabled, save cycles
99-
uint32_t now = millis();
100-
if (now - _lastFastMs >= 1000) { // ~1 Hz cadence
101-
if (_sgp30 && _sgp30->IAQmeasure()) {
102-
_eco2Sum += _sgp30->eCO2; // uint16_t in library
103-
_tvocSum += _sgp30->TVOC; // uint16_t in library
104-
_n++;
105-
}
106-
_lastFastMs = now;
107-
}
100+
return;
101+
102+
// Only perform a single IAQ measurement and cache the result
103+
_did_measure = _sgp30->IAQmeasure();
108104
}
109105

110106
protected:
111107
Adafruit_SGP30 *_sgp30; ///< Pointer to SGP30 sensor object
112108

113-
/** Millis timestamp of last 1 Hz background read. */
114-
uint32_t _lastFastMs = 0;
115-
116-
/** Number of samples accumulated since last publish. */
117-
uint32_t _n = 0;
118-
119-
/** Running sum of eCO2 samples for averaging. */
120-
uint32_t _eco2Sum = 0;
121-
122-
/** Running sum of TVOC samples for averaging. */
123-
uint32_t _tvocSum = 0;
109+
/** Whether we have a fresh IAQ measurement ready. */
110+
bool _did_measure = false;
124111

125112
/*******************************************************************************/
126113
/*!
@@ -134,4 +121,4 @@ class WipperSnapper_I2C_Driver_SGP30 : public WipperSnapper_I2C_Driver {
134121
}
135122
};
136123

137-
#endif // WipperSnapper_I2C_Driver_SGP30
124+
#endif // WipperSnapper_I2C_Driver_SGP30_H

src/components/i2c/drivers/WipperSnapper_I2C_Driver_SGP40.h

Lines changed: 13 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,9 @@ class WipperSnapper_I2C_Driver_SGP40 : public WipperSnapper_I2C_Driver {
7070
_sgp40 = nullptr;
7171
return false;
7272
}
73-
_lastFastMs = millis();
74-
_n = 0;
75-
_vocSum = 0.0f;
76-
_rawSum = 0;
73+
// Initialize cached values
74+
_rawValue = 0;
75+
_vocIdx = 0;
7776
return true;
7877
}
7978

@@ -89,14 +88,7 @@ class WipperSnapper_I2C_Driver_SGP40 : public WipperSnapper_I2C_Driver {
8988
bool getEventRaw(sensors_event_t *rawEvent) override {
9089
if (!_sgp40)
9190
return false;
92-
if (_n > 0) {
93-
rawEvent->data[0] = (float)_rawSum / (float)_n;
94-
_rawSum = 0;
95-
_vocSum = 0.0f;
96-
_n = 0;
97-
return true;
98-
}
99-
rawEvent->data[0] = (float)_sgp40->measureRaw();
91+
rawEvent->data[0] = (float)_rawValue;
10092
return true;
10193
}
10294

@@ -112,22 +104,15 @@ class WipperSnapper_I2C_Driver_SGP40 : public WipperSnapper_I2C_Driver {
112104
bool getEventVOCIndex(sensors_event_t *vocIndexEvent) override {
113105
if (!_sgp40)
114106
return false;
115-
if (_n > 0) {
116-
vocIndexEvent->voc_index = (uint16_t)(_vocSum / (float)_n);
117-
_rawSum = 0;
118-
_vocSum = 0.0f;
119-
_n = 0;
120-
return true;
121-
}
122-
vocIndexEvent->voc_index = (uint16_t)_sgp40->measureVocIndex();
107+
vocIndexEvent->voc_index = (uint16_t)_vocIdx;
123108
return true;
124109
}
125110

126111
/*******************************************************************************/
127112
/*!
128113
@brief Performs background sampling for the SGP40.
129-
Runs once per second to accumulate raw and VOC index values
130-
for later averaging in getEventRaw() and getEventVOCIndex().
114+
single poll (no averaging) and cache
115+
results for getEventRaw()/getEventVOCIndex().
131116
*/
132117
/*******************************************************************************/
133118
void fastTick() override {
@@ -136,29 +121,17 @@ class WipperSnapper_I2C_Driver_SGP40 : public WipperSnapper_I2C_Driver {
136121
if (!vocEnabled())
137122
return;
138123

139-
uint32_t now = millis();
140-
if (now - _lastFastMs >= 1000) {
141-
_rawSum += _sgp40->measureRaw();
142-
_vocSum += _sgp40->measureVocIndex();
143-
_n++;
144-
_lastFastMs = now;
145-
}
124+
// Single poll and cache latest values (no cadence/averaging)
125+
_rawValue = _sgp40->measureRaw();
126+
_vocIdx = (uint16_t)_sgp40->measureVocIndex();
146127
}
147128

148129
protected:
149130
Adafruit_SGP40 *_sgp40; ///< SGP40
150131

151-
/** Millis timestamp of last 1 Hz background read. */
152-
uint32_t _lastFastMs = 0;
153-
154-
/** Number of samples accumulated since last publish. */
155-
uint32_t _n = 0;
156-
157-
/** Running sum of VOC index samples for averaging. */
158-
float _vocSum = 0.0f;
159-
160-
/** Running sum of raw samples for averaging. */
161-
uint32_t _rawSum = 0;
132+
/** Cached latest measurements (no averaging). */
133+
uint16_t _rawValue = 0;
134+
uint16_t _vocIdx = 0;
162135

163136
/*******************************************************************************/
164137
/*!

0 commit comments

Comments
 (0)