Adafruit BME280

Hi Guys,

I using 2 sensors BME280 and SGP30 from adafruit. I wanted to detect if either of the sensor fails how can i know and set the values to zero. I tried with this piece of code where I check if bme.begin() was true then it updated the values and if false it set it as zero but it doesent seem to work. Any idea what i am doing wrong and how can i get this to work

Here is the code

// updating values from the BME280 Board
if(!bme.begin()) {
    temp = 0; 
    pres = 0; 
    hum  = 0;
    Serial.println("BME Failed"); 
   }
if (bme.begin()){
  bme.takeForcedMeasurement();
  temp = bme.readTemperature();                         // Read Temperature
  pres = bme.readPressure()/100.0F;                     // Read Atmospheric Pressure
  hum  = bme.readHumidity();
     
}

// updating values form SPG30 Board

  
if(! sgp.begin()){
    TVOC= 0;  
    CO2= 0;
    
   }
if (sgp.begin()){
   
  sgp.setHumidity(getAbsoluteHumidity(temp, hum));               // Enable the humditiy compensation for the air quality signals
 
  if (! sgp.IAQmeasure()) {
     
    return;
  }
    TVOC= sgp.TVOC;  
    CO2= sgp.eCO2; 
    
  // self-calibrate after taking 30 values
  counter++;
  if (counter == 30) {
    counter = 0;
    uint16_t TVOC_base, eCO2_base;
    if (! sgp.getIAQBaseline(&eCO2_base, &TVOC_base)) {
        return;
        } }                                             // Take mesurements from SGP30
}

Thank you for you help

Post complete code!

I wanted to detect if either of the sensor fails how can i know and set the values to zero.

So you expect the sensor to fail during operation? What kind of failure do you expect? No communication at all, sensing wrong values?

I tried with this piece of code where I check if bme.begin() was true then it updated the values and if false it set it as zero but it doesent seem to work.

What does that mean? Do you have a failing sensor?

You could have more than one sensor and compare them , declaring a fault if they differ by more than a certain value

Sorry, Here is the full code

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include "Adafruit_SGP30.h"

#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME280 bme; // I2C
Adafruit_SGP30 sgp;

unsigned long delayTime;
int counter = 0;
float temp=0 ;                          // Read Temperature from BME280
float pres=0 ;                          // Read Atmospheric Pressure from BME280
double hum =0;                          // Read Humidity from BME280
uint32_t TVOC=0 ;                       // Total Volatile Organic Compound (TVOC) (ppb)
uint32_t CO2=0 ;                        // equivalent carbon dioxide reading (eCO2) (ppm)

uint32_t getAbsoluteHumidity(float temperature, float humidity) {
    // approximation formula from Sensirion SGP30 Driver Integration chapter 3.15
    const float absoluteHumidity = 216.7f * ((humidity / 100.0f) * 6.112f * exp((17.62f * temperature) / (243.12f + temperature)) / (273.15f + temperature)); // [g/m^3]
    const uint32_t absoluteHumidityScaled = static_cast<uint32_t>(1000.0f * absoluteHumidity); // [mg/m^3]
    return absoluteHumidityScaled;
}


void printValues() {
    // updating values from the BME280 Board
if((bme.begin())==0) {
    temp = 0; 
    pres = 0; 
    hum  = 0;
    Serial.println("BME Failed"); 
   }
if (bme.begin()){
  bme.takeForcedMeasurement();
  temp = bme.readTemperature();                         // Read Temperature
  pres = bme.readPressure()/100.0F;                     // Read Atmospheric Pressure
  hum  = bme.readHumidity();
  //Serial.println(bme.begin(0x77, &Wire)); 
    Serial.print("Temperature = ");   Serial.print(temp);     Serial.println(" *C");
    Serial.print("Pressure = ");      Serial.print(pres );    Serial.println(" hPa");
    Serial.print("Humidity = ");      Serial.print(hum);      Serial.println(" %");  
}

// updating values form SPG30 Board
if(! sgp.begin()){
    TVOC= 0;  
    CO2= 0;
    Serial.println("SGP Failed"); 
    }
if (sgp.begin()){
   
  sgp.setHumidity(getAbsoluteHumidity(temp, hum));               // Enable the humditiy compensation for the air quality signals
 
  if (! sgp.IAQmeasure()) {
    return;
  }
    TVOC= sgp.TVOC;  
    CO2= sgp.eCO2; 
    Serial.print("TVOC "); Serial.print(TVOC);  Serial.println(" ppb\t");
    Serial.print("eCO2 "); Serial.print(CO2);   Serial.println(" ppm");   Serial.println("");
    // self-calibrate after taking 30 values
  counter++;
  if (counter == 30) {
    counter = 0;
    uint16_t TVOC_base, eCO2_base;
    if (! sgp.getIAQBaseline(&eCO2_base, &TVOC_base)) {
        return;
        } }                                             // Take mesurements from SGP30
}  
}

void setup() {
    Serial.begin(9600);
    while(!Serial);    // time to get serial running
    Serial.println(F("BME280 and SGP30 test"));

    unsigned status;
    
    // default settings
    status = bme.begin();  
    // You can also pass in a Wire library object like &Wire2
    // status = bme.begin(0x76, &Wire2)
    if (!status) {
        Serial.println("BME280 not found");
        while (1) delay(10);
    if (! sgp.begin()){
        Serial.println("SGP30 not found");
        while (1);
    }
    
    //delayTime = 20000;
    Serial.println();
}
}

void loop() { 
    printValues();

    delay(20000); // 20 sec
    if (counter == 30) {
    counter = 0;

    uint16_t TVOC_base, eCO2_base;
    if (! sgp.getIAQBaseline(&eCO2_base, &TVOC_base)) {
      Serial.println("Failed to get baseline readings");
      return;
      }
    }
    
}

First of all, thank you for your replies.

The reason to detect sensor fault is because i am using this 2 sensors for a weather station who will transmit data by sms once every hour (i haven’t got to that part yet) and since this weather station will be at a remote site (at a mountain peak) i wanted to detect if either of the sensor got damaged due to humidity or water going in the shield during rain. most of the time the bme280 code just displays “nan” when i remove the power from the sensor indicating a fault. and when i put power back it works again but when i remove the power and sensor fails to get readings i want all values to go to 0

if(! sgp.begin()){
    TVOC= 0;  
    CO2= 0;
    Serial.println("SGP Failed"); 
    }

That’s why i added this line. but i just found out that the function “bme.begin()” only needs to be called once and it gives “True” always even if sensor fails half way in operation.

What i was going to try now is, i found many codes for scanning I2C address and i can use that in my main loop to check if either of the sensor failed or stooped working.

If anyone has better suggestion please let me know.

Thank You
Vishal.

Something like…

  scratchfloat = bme.readTemperature();
  if(isnan(scratchfloat) || (scratchfloat == 0))
  {
    scratchfloat = temperature;                             // Just use last value instead to prevent perpetual NaN
    sendStatus(LoRaDevice " Temperature Reboot.");
    resetNeeded = true;
  }
  temperature += scratchfloat;

but replace the “scratchfloat = temperature;” with “scratchfloat = 0;”

The BME280 reset code I use when a NaN is read is…

void BME280_Reset()
{
  if(DEBUG) Serial.println(F("BME280 Reset"));
  Wire.beginTransmission(BME280_I2C_ADDR);
  Wire.write((uint8_t)BME280_REGISTER_SOFTRESET);
  Wire.write((uint8_t)0xB6);
  Wire.endTransmission();
  delay(1000);
}

most of the time the bme280 code just displays "nan" when i remove the power from the sensor indicating a fault

Are you sure a faulty sensor is behaving like one without power?

i wanted to detect if either of the sensor got damaged due to humidity or water going in the shield during rain.

I would expect it to return wrong values long before it doesn't react (like if it has no power). So checking the returned values for plausibility is probably a better approach.