From 4eb816e2cc81321f191a65cc8fbf158f626c5958 Mon Sep 17 00:00:00 2001 From: tyeth Date: Thu, 19 Sep 2024 14:11:49 +0100 Subject: [PATCH 1/3] Add retry if data not ready for SCD30 --- .../drivers/WipperSnapper_I2C_Driver_SCD30.h | 85 ++++++++++++++----- 1 file changed, 64 insertions(+), 21 deletions(-) diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SCD30.h b/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SCD30.h index cb7c409b5..70b3d0ac4 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SCD30.h +++ b/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SCD30.h @@ -24,7 +24,8 @@ @brief Class that provides a driver interface for the SCD30 sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_SCD30 : public WipperSnapper_I2C_Driver { +class WipperSnapper_I2C_Driver_SCD30 : public WipperSnapper_I2C_Driver +{ public: /*******************************************************************************/ @@ -37,7 +38,8 @@ class WipperSnapper_I2C_Driver_SCD30 : public WipperSnapper_I2C_Driver { */ /*******************************************************************************/ WipperSnapper_I2C_Driver_SCD30(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) { + : WipperSnapper_I2C_Driver(i2c, sensorAddress) + { _i2c = i2c; _sensorAddress = sensorAddress; } @@ -48,11 +50,47 @@ class WipperSnapper_I2C_Driver_SCD30 : public WipperSnapper_I2C_Driver { @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() { + bool begin() + { _scd = new Adafruit_SCD30(); return _scd->begin((uint8_t)_sensorAddress, _i2c); } + /*******************************************************************************/ + /*! + @brief Reads the SCD30 sensor. + @returns True if the sensor was read successfully, False otherwise. + */ + /*******************************************************************************/ + bool readSensor() + { + // dont read sensor more than once per second + if (_lastRead != 0 && millis() - _lastRead < 1000) + { + return true; + } + + if (!_scd->dataReady()) + { + delay(100); + if (!_scd->dataReady()) + { + return false; + } + } + sensors_event_t tempEvent; + sensors_event_t humidEvent; + if (!_scd->getEvent(&humidEvent, &tempEvent)) + { + return false; + } + _temperature = tempEvent.temperature; + _humidity = humidEvent.relative_humidity; + _CO2 = _scd->CO2; + _lastRead = millis(); + return true; + } + /*******************************************************************************/ /*! @brief Gets the SCD30's current temperature. @@ -62,16 +100,15 @@ class WipperSnapper_I2C_Driver_SCD30 : public WipperSnapper_I2C_Driver { otherwise. */ /*******************************************************************************/ - bool getEventAmbientTemp(sensors_event_t *tempEvent) { + bool getEventAmbientTemp(sensors_event_t *tempEvent) + { // check if sensor is enabled and data is available - if (_tempSensorPeriod != 0 && (!_scd->dataReady())) - return false; - - // attempt to get temperature data - sensors_event_t humidEvent; - if (!_scd->getEvent(&humidEvent, tempEvent)) + if (!readSensor()) + { return false; + } + tempEvent->temperature = _temperature; return true; } @@ -84,16 +121,15 @@ class WipperSnapper_I2C_Driver_SCD30 : public WipperSnapper_I2C_Driver { otherwise. */ /*******************************************************************************/ - bool getEventRelativeHumidity(sensors_event_t *humidEvent) { + bool getEventRelativeHumidity(sensors_event_t *humidEvent) + { // check if sensor is enabled and data is available - if (_humidSensorPeriod != 0 && (!_scd->dataReady())) - return false; - - // attempt to get temperature data - sensors_event_t tempEvent; - if (!_scd->getEvent(humidEvent, &tempEvent)) + if (!readSensor()) + { return false; + } + humidEvent->relative_humidity = _humidity; return true; } @@ -106,17 +142,24 @@ class WipperSnapper_I2C_Driver_SCD30 : public WipperSnapper_I2C_Driver { otherwise. */ /*******************************************************************************/ - bool getEventCO2(sensors_event_t *co2Event) { + bool getEventCO2(sensors_event_t *co2Event) + { // check if sensor is enabled and data is available - if (_CO2SensorPeriod != 0 && (!_scd->dataReady())) + if (!readSensor()) + { return false; + } - co2Event->CO2 = _scd->CO2; + co2Event->CO2 = _CO2; return true; } protected: - Adafruit_SCD30 *_scd; ///< SCD30 driver object + Adafruit_SCD30 *_scd = nullptr; ///< SCD30 driver object + ulong _lastRead = 0; ///< Last time the sensor was read + float _temperature = 0; ///< Temperature + float _humidity = 0; ///< Relative Humidity + float _CO2 = 0; ///< CO2 }; #endif // WipperSnapper_I2C_Driver_SCD30 \ No newline at end of file From 8ee25a5fead6da69602922fbb8a6274b2c2f6f2e Mon Sep 17 00:00:00 2001 From: tyeth Date: Thu, 19 Sep 2024 19:37:14 +0100 Subject: [PATCH 2/3] format SCD30 --- .../drivers/WipperSnapper_I2C_Driver_SCD30.h | 42 +++++++------------ 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SCD30.h b/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SCD30.h index 70b3d0ac4..ac6383917 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SCD30.h +++ b/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SCD30.h @@ -24,8 +24,7 @@ @brief Class that provides a driver interface for the SCD30 sensor. */ /**************************************************************************/ -class WipperSnapper_I2C_Driver_SCD30 : public WipperSnapper_I2C_Driver -{ +class WipperSnapper_I2C_Driver_SCD30 : public WipperSnapper_I2C_Driver { public: /*******************************************************************************/ @@ -38,8 +37,7 @@ class WipperSnapper_I2C_Driver_SCD30 : public WipperSnapper_I2C_Driver */ /*******************************************************************************/ WipperSnapper_I2C_Driver_SCD30(TwoWire *i2c, uint16_t sensorAddress) - : WipperSnapper_I2C_Driver(i2c, sensorAddress) - { + : WipperSnapper_I2C_Driver(i2c, sensorAddress) { _i2c = i2c; _sensorAddress = sensorAddress; } @@ -50,8 +48,7 @@ class WipperSnapper_I2C_Driver_SCD30 : public WipperSnapper_I2C_Driver @returns True if initialized successfully, False otherwise. */ /*******************************************************************************/ - bool begin() - { + bool begin() { _scd = new Adafruit_SCD30(); return _scd->begin((uint8_t)_sensorAddress, _i2c); } @@ -62,26 +59,21 @@ class WipperSnapper_I2C_Driver_SCD30 : public WipperSnapper_I2C_Driver @returns True if the sensor was read successfully, False otherwise. */ /*******************************************************************************/ - bool readSensor() - { + bool readSensor() { // dont read sensor more than once per second - if (_lastRead != 0 && millis() - _lastRead < 1000) - { + if (_lastRead != 0 && millis() - _lastRead < 1000) { return true; } - if (!_scd->dataReady()) - { + if (!_scd->dataReady()) { delay(100); - if (!_scd->dataReady()) - { + if (!_scd->dataReady()) { return false; } } sensors_event_t tempEvent; sensors_event_t humidEvent; - if (!_scd->getEvent(&humidEvent, &tempEvent)) - { + if (!_scd->getEvent(&humidEvent, &tempEvent)) { return false; } _temperature = tempEvent.temperature; @@ -100,11 +92,9 @@ class WipperSnapper_I2C_Driver_SCD30 : public WipperSnapper_I2C_Driver otherwise. */ /*******************************************************************************/ - bool getEventAmbientTemp(sensors_event_t *tempEvent) - { + bool getEventAmbientTemp(sensors_event_t *tempEvent) { // check if sensor is enabled and data is available - if (!readSensor()) - { + if (!readSensor()) { return false; } @@ -121,11 +111,9 @@ class WipperSnapper_I2C_Driver_SCD30 : public WipperSnapper_I2C_Driver otherwise. */ /*******************************************************************************/ - bool getEventRelativeHumidity(sensors_event_t *humidEvent) - { + bool getEventRelativeHumidity(sensors_event_t *humidEvent) { // check if sensor is enabled and data is available - if (!readSensor()) - { + if (!readSensor()) { return false; } @@ -142,11 +130,9 @@ class WipperSnapper_I2C_Driver_SCD30 : public WipperSnapper_I2C_Driver otherwise. */ /*******************************************************************************/ - bool getEventCO2(sensors_event_t *co2Event) - { + bool getEventCO2(sensors_event_t *co2Event) { // check if sensor is enabled and data is available - if (!readSensor()) - { + if (!readSensor()) { return false; } From d1898c962de9f3835946e0ef41c6c912807b7a33 Mon Sep 17 00:00:00 2001 From: tyeth Date: Tue, 24 Sep 2024 16:44:56 +0100 Subject: [PATCH 3/3] Refactor SCD30 to improve readability --- .../drivers/WipperSnapper_I2C_Driver_SCD30.h | 64 ++++++++++++------- 1 file changed, 42 insertions(+), 22 deletions(-) diff --git a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SCD30.h b/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SCD30.h index ac6383917..fcaa1d94d 100644 --- a/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SCD30.h +++ b/src/components/i2c/drivers/WipperSnapper_I2C_Driver_SCD30.h @@ -53,32 +53,52 @@ class WipperSnapper_I2C_Driver_SCD30 : public WipperSnapper_I2C_Driver { return _scd->begin((uint8_t)_sensorAddress, _i2c); } + /*******************************************************************************/ + /*! + @brief Checks if sensor was read within last 1s, or is the first read. + @returns True if the sensor was recently read, False otherwise. + */ + bool alreadyRecentlyRead() { + return (_lastRead != 0 && millis() - _lastRead) < 1000; + } + + /*******************************************************************************/ + /*! + @brief Checks if the sensor is ready to be read + @returns True if the sensor is ready, False otherwise. + */ + /*******************************************************************************/ + bool sensorReady() { + if (!_scd->dataReady()) { + // failed, one more quick attempt + delay(100); + if (!_scd->dataReady()) { + return false; + } + } + return true; + } + /*******************************************************************************/ /*! @brief Reads the SCD30 sensor. @returns True if the sensor was read successfully, False otherwise. */ /*******************************************************************************/ - bool readSensor() { + bool readSensorData() { // dont read sensor more than once per second - if (_lastRead != 0 && millis() - _lastRead < 1000) { + if (alreadyRecentlyRead()) { return true; } - if (!_scd->dataReady()) { - delay(100); - if (!_scd->dataReady()) { - return false; - } + if (!sensorReady()) { + return false; } - sensors_event_t tempEvent; - sensors_event_t humidEvent; - if (!_scd->getEvent(&humidEvent, &tempEvent)) { + + if (_scd->getEvent(&_humidity, &_temperature)) { return false; } - _temperature = tempEvent.temperature; - _humidity = humidEvent.relative_humidity; - _CO2 = _scd->CO2; + _CO2.CO2 = _scd->CO2; _lastRead = millis(); return true; } @@ -94,11 +114,11 @@ class WipperSnapper_I2C_Driver_SCD30 : public WipperSnapper_I2C_Driver { /*******************************************************************************/ bool getEventAmbientTemp(sensors_event_t *tempEvent) { // check if sensor is enabled and data is available - if (!readSensor()) { + if (!readSensorData()) { return false; } - tempEvent->temperature = _temperature; + tempEvent = &_temperature; return true; } @@ -113,11 +133,11 @@ class WipperSnapper_I2C_Driver_SCD30 : public WipperSnapper_I2C_Driver { /*******************************************************************************/ bool getEventRelativeHumidity(sensors_event_t *humidEvent) { // check if sensor is enabled and data is available - if (!readSensor()) { + if (!readSensorData()) { return false; } - humidEvent->relative_humidity = _humidity; + humidEvent = &_humidity; return true; } @@ -132,20 +152,20 @@ class WipperSnapper_I2C_Driver_SCD30 : public WipperSnapper_I2C_Driver { /*******************************************************************************/ bool getEventCO2(sensors_event_t *co2Event) { // check if sensor is enabled and data is available - if (!readSensor()) { + if (!readSensorData()) { return false; } - co2Event->CO2 = _CO2; + co2Event = &_CO2; return true; } protected: Adafruit_SCD30 *_scd = nullptr; ///< SCD30 driver object ulong _lastRead = 0; ///< Last time the sensor was read - float _temperature = 0; ///< Temperature - float _humidity = 0; ///< Relative Humidity - float _CO2 = 0; ///< CO2 + sensors_event_t _temperature; ///< Temperature + sensors_event_t _humidity; ///< Relative Humidity + sensors_event_t _CO2; ///< CO2 }; #endif // WipperSnapper_I2C_Driver_SCD30 \ No newline at end of file