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
129147protected:
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