From 847ea9692fd4459acb82f7d2065635bb5bc82b9d Mon Sep 17 00:00:00 2001 From: tyeth Date: Thu, 15 Dec 2022 22:53:52 +0000 Subject: [PATCH] Add new voc/nox index types + update SEN55 driver Final piece of https://github.com/adafruit/Wippersnapper_Components/issues/103 --- src/components/i2c/WipperSnapper_I2C.cpp | 43 +++++++ .../i2c/drivers/WipperSnapper_I2C_Driver.h | 117 ++++++++++++++++++ .../drivers/WipperSnapper_I2C_Driver_SEN5X.h | 50 ++++++-- src/wippersnapper/i2c/v1/i2c.pb.h | 4 +- 4 files changed, 202 insertions(+), 12 deletions(-) diff --git a/src/components/i2c/WipperSnapper_I2C.cpp b/src/components/i2c/WipperSnapper_I2C.cpp index 468870e2c..e2c0d051d 100644 --- a/src/components/i2c/WipperSnapper_I2C.cpp +++ b/src/components/i2c/WipperSnapper_I2C.cpp @@ -945,6 +945,49 @@ void WipperSnapper_Component_I2C::update() { (*iter)->setSensorGasResistancePeriodPrv(curTime); } + // NOx-index sensor + curTime = millis(); + if ((*iter)->getSensorNOxIndexPeriod() != 0L && + curTime - (*iter)->getSensorNOxIndexPeriodPrv() > + (*iter)->getSensorNOxIndexPeriod()) { + if ((*iter)->getEventNOxIndex(&event)) { + WS_DEBUG_PRINT("Sensor 0x"); + WS_DEBUG_PRINTHEX((*iter)->getI2CAddress()); + WS_DEBUG_PRINTLN(""); + WS_DEBUG_PRINT("\tNOx Index: "); + WS_DEBUG_PRINT(event.nox_index); + + fillEventMessage( + &msgi2cResponse, event.data[0], + wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_NOX_INDEX); + } else { + WS_DEBUG_PRINTLN( + "ERROR: Failed to obtain NOx index sensor reading!"); + } + (*iter)->setSensorNOxIndexPeriodPrv(curTime); + } + + // VOC-index sensor + curTime = millis(); + if ((*iter)->getSensorVOCIndexPeriod() != 0L && + curTime - (*iter)->getSensorVOCIndexPeriodPrv() > + (*iter)->getSensorVOCIndexPeriod()) { + if ((*iter)->getEventVOCIndex(&event)) { + WS_DEBUG_PRINT("Sensor 0x"); + WS_DEBUG_PRINTHEX((*iter)->getI2CAddress()); + WS_DEBUG_PRINTLN(""); + WS_DEBUG_PRINT("\tVOC Index: "); + WS_DEBUG_PRINT(event.voc_index); + + fillEventMessage( + &msgi2cResponse, event.data[0], + wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_VOC_INDEX); + } else { + WS_DEBUG_PRINTLN( + "ERROR: Failed to obtain VOC index sensor reading!"); + } + (*iter)->setSensorVOCIndexPeriodPrv(curTime); + } // Proximity sensor curTime = millis(); if ((*iter)->sensorProximityPeriod() != 0L && diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver.h b/src/components/i2c/drivers/WipperSnapper_I2C_Driver.h index a3ab01dfd..d5df88d67 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver.h +++ b/src/components/i2c/drivers/WipperSnapper_I2C_Driver.h @@ -121,6 +121,12 @@ class WipperSnapper_I2C_Driver { case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_GAS_RESISTANCE: _gasResistancePeriod = sensorPeriod; break; + case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_NOX_INDEX: + _NOxIndexPeriod = sensorPeriod; + break; + case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_VOC_INDEX: + _VOCIndexPeriod = sensorPeriod; + break; default: break; } @@ -926,6 +932,109 @@ class WipperSnapper_I2C_Driver { return false; } + /****************************** SENSOR_TYPE: NOx Index (index) + * *******************************/ + /*********************************************************************************/ + /*! + @brief Base implementation - Returns the NOx Index + sensor's period, if set. + @returns Time when the NOx Index sensor should be polled, + in seconds. + */ + /*********************************************************************************/ + virtual long getSensorNOxIndexPeriod() { return _NOxIndexPeriod; } + + /*********************************************************************************/ + /*! + @brief Base implementation - Returns the previous time interval at + which the NOx Index sensor was queried last. + @returns Time when the NOx Index sensor was last queried, + in seconds. + */ + /*********************************************************************************/ + virtual long getSensorNOxIndexPeriodPrv() { + return _NOxIndexPeriodPrv; + } + + /*******************************************************************************/ + /*! + @brief Sets a timestamp for when the object NOx Index sensor + was queried. + @param period + The time when the NOx Index sensor was queried + last. + */ + /*******************************************************************************/ + virtual void setSensorNOxIndexPeriodPrv(long period) { + _NOxIndexPeriodPrv = period; + } + + /*******************************************************************************/ + /*! + @brief Base implementation - Reads a NOx Index sensor and converts + the reading into the expected SI unit. + @param gasEvent + NOx Index sensor reading, in ohms. + @returns True if the sensor event was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + virtual bool getEventNOxIndex(sensors_event_t *gasEvent) { + return false; + } + + /****************************** SENSOR_TYPE: VOC Index (index) + * *******************************/ + /*********************************************************************************/ + /*! + @brief Base implementation - Returns the VOC Index + sensor's period, if set. + @returns Time when the VOC Index sensor should be polled, + in seconds. + */ + /*********************************************************************************/ + virtual long getSensorVOCIndexPeriod() { return _VOCIndexPeriod; } + + /*********************************************************************************/ + /*! + @brief Base implementation - Returns the previous time interval at + which the VOC Index sensor was queried last. + @returns Time when the VOC Index sensor was last queried, + in seconds. + */ + /*********************************************************************************/ + virtual long getSensorVOCIndexPeriodPrv() { + return _VOCIndexPeriodPrv; + } + + /*******************************************************************************/ + /*! + @brief Sets a timestamp for when the object VOC Index sensor + was queried. + @param period + The time when the VOC Index sensor was queried + last. + */ + /*******************************************************************************/ + virtual void setSensorVOCIndexPeriodPrv(long period) { + _VOCIndexPeriodPrv = period; + } + + /*******************************************************************************/ + /*! + @brief Base implementation - Reads a VOC Index sensor and converts + the reading into the expected SI unit. + @param gasEvent + VOC Index sensor reading, in ohms. + @returns True if the sensor event was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + virtual bool getEventVOCIndex(sensors_event_t *gasEvent) { + return false; + } + + /**************************** SENSOR_TYPE: PROXIMITY * ****************************/ /*******************************************************************************/ @@ -1081,6 +1190,14 @@ class WipperSnapper_I2C_Driver { ///< gas resistance sensor's value. long _gasResistancePeriodPrv = 0L; ///< The time when the gas resistance ///< sensor was last read. + long _NOxIndexPeriod = 0L; ///< The time period between reading the + ///< NOx Index sensor's value. + long _NOxIndexPeriodPrv = 0L; ///< The time when the NOx Index + ///< sensor was last read. + long _VOCIndexPeriod = 0L; ///< The time period between reading the + ///< VOC Index sensor's value. + long _VOCIndexPeriodPrv = 0L; ///< The time when the VOC Index + ///< sensor was last read. long _proximitySensorPeriod = 0L; ///< The time period between reading the ///< proximity sensor's value. long _proximitySensorPeriodPrv = 0L; ///< The time when the proximity sensor diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SEN5X.h b/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SEN5X.h index 9908bae0c..a1fe1ef54 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SEN5X.h +++ b/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SEN5X.h @@ -59,7 +59,8 @@ class WipperSnapper_I2C_Driver_SEN5X : public WipperSnapper_I2C_Driver { if (error_stop != 0) { return false; } - delay(1100); // Wait 1 second for sensors to start recording + 100ms for reset + // Wait 1 second for sensors to start recording + 100ms for reset i2c command + delay(1100); u_int16_t error_start = _sen->startMeasurement(); if (error_start != 0) { return false; @@ -124,20 +125,48 @@ class WipperSnapper_I2C_Driver_SEN5X : public WipperSnapper_I2C_Driver { /*******************************************************************************/ /*! - @brief Gets the SEN5X's current NOX/VOC reading. - @param rawEvent - Adafruit Sensor event for Raw data (4 float array) + @brief Gets the SEN5X's current NOX reading. + @param noxIndexEvent + Adafruit Sensor event for NOx Index (1-500, 100 is normal) @returns True if the sensor value was obtained successfully, False otherwise. */ /*******************************************************************************/ - bool getEventRaw(sensors_event_t *rawEvent) { - float massConcentrationPm1p0, massConcentrationPm2p5, - massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity, - ambientTemperature, vocIndex, noxIndex; + bool getEventNOxIndex(sensors_event_t *noxIndexEvent) { + u_int16_t massConcentrationPm1p0, massConcentrationPm2p5, + massConcentrationPm4p0, massConcentrationPm10p0; + int16_t ambientHumidity, ambientTemperature, vocIndex, noxIndex; uint16_t error; - error = _sen->readMeasuredValues( + error = _sen->readMeasuredValuesAsIntegers( + massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0, + massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex, + noxIndex); + if ((_rawSensorPeriod != 0 && error) || noxIndex == 0 || vocIndex == 0) { + return false; + } + + noxIndexEvent->nox_index = noxIndex; + return true; + } + + + /*******************************************************************************/ + /*! + @brief Gets the SEN5X's current VOC reading. + @param vocIndexEvent + Adafruit Sensor event for VOC Index (1-500, 100 is normal) + @returns True if the sensor value was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + bool getEventVOCIndex(sensors_event_t *vocIndexEvent) { + u_int16_t massConcentrationPm1p0, massConcentrationPm2p5, + massConcentrationPm4p0, massConcentrationPm10p0; + int16_t ambientHumidity, ambientTemperature, vocIndex, noxIndex; + uint16_t error; + + error = _sen->readMeasuredValuesAsIntegers( massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex, noxIndex); @@ -145,8 +174,7 @@ class WipperSnapper_I2C_Driver_SEN5X : public WipperSnapper_I2C_Driver { return false; } - rawEvent->data[0] = noxIndex; // alphabetical? - rawEvent->data[1] = vocIndex; + vocIndexEvent->voc_index = vocIndex; return true; } diff --git a/src/wippersnapper/i2c/v1/i2c.pb.h b/src/wippersnapper/i2c/v1/i2c.pb.h index 0d64a64ad..ce352fa22 100644 --- a/src/wippersnapper/i2c/v1/i2c.pb.h +++ b/src/wippersnapper/i2c/v1/i2c.pb.h @@ -54,7 +54,9 @@ typedef enum _wippersnapper_i2c_v1_SensorType { wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_ECO2 = 29, wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_UNITLESS_PERCENT = 30, wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_AMBIENT_TEMPERATURE_FAHRENHEIT = 31, - wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE_FAHRENHEIT = 32 + wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_OBJECT_TEMPERATURE_FAHRENHEIT = 32, + wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_NOX_INDEX = 33, + wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_VOC_INDEX = 34 } wippersnapper_i2c_v1_SensorType; /* Struct definitions */