Skip to content

Commit 0a0927d

Browse files
committed
SGP30/40: add fastTick 1Hz cadence, simplify caching, update docs
1 parent 557a0f4 commit 0a0927d

File tree

3 files changed

+62
-18
lines changed

3 files changed

+62
-18
lines changed

src/components/i2c/drivers/WipperSnapper_I2C_Driver.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1414,8 +1414,8 @@ class WipperSnapper_I2C_Driver {
14141414
long _ambientTempFPeriod = 0L; ///< The time period between reading the
14151415
///< ambient temp. (°F) sensor's value.
14161416
long _ambientTempFPeriodPrv =
1417-
PERIOD_24HRS_AGO_MILLIS; ///< The time when the ambient temp. (°F) sensor
1418-
///< was last read.
1417+
PERIOD_24HRS_AGO_MILLIS; ///< The time when the ambient temp. (°F) sensor
1418+
///< was last read.
14191419
long _objectTempFPeriod = 0L; ///< The time period between reading the object
14201420
///< temp. (°F) sensor's value.
14211421
long _objectTempFPeriodPrv =

src/components/i2c/drivers/WipperSnapper_I2C_Driver_SGP30.h

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include "WipperSnapper_I2C_Driver.h"
55
#include <Adafruit_SGP30.h>
66

7+
#define SGP30_FASTTICK_INTERVAL_MS 1000 ///< Enforce ~1 Hz cadence
8+
79
/**************************************************************************/
810
/*!
911
@brief Class that provides a driver interface for a SGP30 sensor.
@@ -54,6 +56,7 @@ class WipperSnapper_I2C_Driver_SGP30 : public WipperSnapper_I2C_Driver {
5456
}
5557
_sgp30->IAQinit(); // start IAQ algorithm
5658
_did_measure = false;
59+
_lastFastMs = millis() - SGP30_FASTTICK_INTERVAL_MS;
5760
return true;
5861
}
5962

@@ -87,10 +90,22 @@ class WipperSnapper_I2C_Driver_SGP30 : public WipperSnapper_I2C_Driver {
8790

8891
/*******************************************************************************/
8992
/*!
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.
93+
@brief Performs background sampling for the SGP30.
94+
95+
This method enforces a ~1 Hz cadence recommended by the sensor
96+
datasheet. On each call, it checks the elapsed time since the
97+
last poll using `millis()`. If at least
98+
SGP30_FASTTICK_INTERVAL_MS have passed, it performs a single
99+
IAQ measurement and caches the result in `_did_measure`.
100+
101+
Cached values (eCO2, TVOC) are later returned by
102+
`getEventECO2()` and `getEventTVOC()` without re-triggering I2C
103+
traffic.
104+
105+
@note Called automatically from
106+
`WipperSnapper_Component_I2C::update()` once per loop iteration.
107+
Must be non-blocking (no delays). The millis-based guard ensures
108+
the sensor is not over-polled.
94109
*/
95110
/*******************************************************************************/
96111
void fastTick() override {
@@ -99,8 +114,11 @@ class WipperSnapper_I2C_Driver_SGP30 : public WipperSnapper_I2C_Driver {
99114
if (!iaqEnabled())
100115
return;
101116

102-
// Only perform a single IAQ measurement and cache the result
103-
_did_measure = _sgp30->IAQmeasure();
117+
uint32_t now = millis();
118+
if (now - _lastFastMs >= SGP30_FASTTICK_INTERVAL_MS) {
119+
_did_measure = _sgp30->IAQmeasure();
120+
_lastFastMs = now;
121+
}
104122
}
105123

106124
protected:
@@ -109,6 +127,9 @@ class WipperSnapper_I2C_Driver_SGP30 : public WipperSnapper_I2C_Driver {
109127
/** Whether we have a fresh IAQ measurement ready. */
110128
bool _did_measure = false;
111129

130+
/** Timestamp of last poll to enforce 1 Hz cadence. */
131+
uint32_t _lastFastMs = 0;
132+
112133
/*******************************************************************************/
113134
/*!
114135
@brief Returns whether IAQ background sampling should be active.

src/components/i2c/drivers/WipperSnapper_I2C_Driver_SGP40.h

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#include <Adafruit_SGP40.h>
2121
#include <Wire.h>
2222

23+
#define SGP40_FASTTICK_INTERVAL_MS 1000 ///< Enforce ~1 Hz cadence
24+
2325
/**************************************************************************/
2426
/*!
2527
@brief Class that provides a driver interface for the SGP40 sensor.
@@ -73,6 +75,7 @@ class WipperSnapper_I2C_Driver_SGP40 : public WipperSnapper_I2C_Driver {
7375
// Initialize cached values
7476
_rawValue = 0;
7577
_vocIdx = 0;
78+
_lastFastMs = millis() - SGP40_FASTTICK_INTERVAL_MS;
7679
return true;
7780
}
7881

@@ -110,9 +113,21 @@ class WipperSnapper_I2C_Driver_SGP40 : public WipperSnapper_I2C_Driver {
110113

111114
/*******************************************************************************/
112115
/*!
113-
@brief Performs background sampling for the SGP40.
114-
single poll (no averaging) and cache
115-
results for getEventRaw()/getEventVOCIndex().
116+
@brief Performs background sampling for the SGP40.
117+
118+
This method enforces a ~1 Hz cadence recommended by the sensor
119+
datasheet. On each call, it checks the elapsed time since the last
120+
poll using `millis()`. If at least SGP40_FASTTICK_INTERVAL_MS ms
121+
have passed, it reads a new raw value and VOC index from the
122+
sensor and caches them in `_rawValue` and `_vocIdx`.
123+
124+
Cached results are later returned by `getEventRaw()` and
125+
`getEventVOCIndex()` without re-triggering I2C traffic.
126+
127+
@note Called automatically from
128+
`WipperSnapper_Component_I2C::update()` once per loop iteration.
129+
Must be non-blocking (no delays). The millis-based guard ensures
130+
the sensor is not over-polled.
116131
*/
117132
/*******************************************************************************/
118133
void fastTick() override {
@@ -121,17 +136,25 @@ class WipperSnapper_I2C_Driver_SGP40 : public WipperSnapper_I2C_Driver {
121136
if (!vocEnabled())
122137
return;
123138

124-
// Single poll and cache latest values (no cadence/averaging)
125-
_rawValue = _sgp40->measureRaw();
126-
_vocIdx = (uint16_t)_sgp40->measureVocIndex();
139+
uint32_t now = millis();
140+
if (now - _lastFastMs >= SGP40_FASTTICK_INTERVAL_MS) {
141+
_rawValue = _sgp40->measureRaw();
142+
_vocIdx = (int32_t)_sgp40->measureVocIndex();
143+
_lastFastMs = now;
144+
}
127145
}
128146

129147
protected:
130-
Adafruit_SGP40 *_sgp40; ///< SGP40
148+
Adafruit_SGP40 *_sgp40; ///< Pointer to SGP40 sensor object
131149

132-
/** Cached latest measurements (no averaging). */
133-
uint16_t _rawValue = 0;
134-
uint16_t _vocIdx = 0; ///< VOC index value (0–500)
150+
/**
151+
* Cached latest measurements from the sensor.
152+
* - _rawValue: raw sensor output (ticks)
153+
* - _vocIdx: VOC Index (signed, per datasheet)
154+
*/
155+
uint16_t _rawValue = 0; ///< Raw sensor output (ticks)
156+
int32_t _vocIdx = 0; ///< VOC Index (signed, per datasheet)
157+
uint32_t _lastFastMs = 0; ///< Last poll timestamp to enforce 1 Hz cadence
135158

136159
/*******************************************************************************/
137160
/*!

0 commit comments

Comments
 (0)