BMP280 starts to show wrong barometer readings after one day

My problem is that BMP280 starts to show wrong barometer readings after running one day. After rebooting Nano it is working fine again but around 16 to 24 hours it starts again to show wrong readings.

Readings are higher than they should be. The right values are normally between 1000-1030 hPa and BMP280 starts give wrong readings around from 1045 to 1080 hPa.

The sensor is read in every 10th second.

I think I should somehow initialiaze the sensor between readings in the code but trying to figure it out from the library code was over my understanding. I use I2C-Sensor-Lib_iLib library to read the sensor.

Can someone give any hint how to try solve this problem?

There is also DS3231 Real time clock, DHT22 temperature sensor and SSD1306 Oled display connected to this, but as far as I understand they should not have any effect on how the BMP280 is working.

Code for the project.

// Date and time functions using a DS3231 RTC connected via I2C and Wire lib
// Credits for rtclib to : Code by JeeLabs http://news.jeelabs.org/code/  Released to the public domain! Enjoy!

// Converted so that RTC uses UTC time instead of the local time
// Scion Riverson 2018

// I2C
#include <Wire.h>

//Clock
#include "RTClib.h"

RTC_DS3231 rtc;   // create RTC object

//Display
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#define OLED_ADDR   0x3C

Adafruit_SSD1306 display(-1);

#if (SSD1306_LCDHEIGHT != 64)
#error ("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

//BMP280 sensor
#include "i2c.h"
#include "i2c_BMP280.h"
BMP280 bmp280;

//DHT22 anturi
#include <SimpleDHT.h>
// for DHT22,
//      VCC: 5V or 3V
//      GND: GND
//      DATA: 2
int pinDHT22 = 2;
SimpleDHT22 dht22(pinDHT22);

// CLOCK MUST BE SET IN CORRECT TIME SEPARATELY
// timezone offsets in seconds for West European Time / West European Summer Time WET/WEST
// change these to your own timezone
// more information available in linux with command: zdump -v timezone
// for example : zdump -v Atlantic/Canary
// Check functions is_Dls_On() (Is Daylight Saving On), getUtcTime() and getLocalTime() later on this code

// these timezone settings must be set correctly for your timezone when you want to setup RTC time to UTC automatically from computer
// 1 hour = 3600 seconds

// timezone offset for Atlantic/Canary
unsigned long     dls_On_Offset = 3600;   // Summer time offset in seconds to UTC time when Day light saving is On
unsigned long     dls_Off_Offset = 0;     // Winter time offset in seconds to UTC time when Day light saving is Off

char strDate[11];           //date string
char strTime[9];            //time string
char strTemp[9];           //temp & press strings
char strPres[9];           //
char strHumi[9];

void setup() {
  Serial.begin(9600);       // open serial connection
  delay(500);               // wait for console opening

  if (! rtc.begin()) {      // rtc.begin() - initialize clock routines for use
    Serial.println("Couldn't find RTC");
    while (1);              // stop here
  }

  //setup sensor
  bmp280.initialize();
  bmp280.setEnabled(0);
  bmp280.triggerMeasurement();

  // initialize and clear display
  display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR);
  display.clearDisplay();
  display.display();
  display.setTextSize(2);
  display.setTextColor(WHITE);
}

void loop() {
  float tempBMP280;
  float tempDHT22;
  float pres;
  float humi;
  DateTime nyt;

  nyt = rtc.now();
  // read and show sensors every 10th second
  if (nyt.second() % 10 == 0) {
    //read BMP280
    bmp280.triggerMeasurement();
    bmp280.awaitMeasurement();
    //bmp280.getTemperature(tempBMP280);  // BMP280 temperature is not used in this application
    bmp280.getPressure(pres);
    pres /= 100;

    //dtostrf(tempBMP280, 8, 1, strTemp); // BMP280 temperature is not used in this application
    dtostrf(pres, 6, 1, strPres);

    //read DHT22
    int err = SimpleDHTErrSuccess;
    err = dht22.read2(&tempDHT22, &humi, NULL);
    dtostrf(tempDHT22, 6, 1, strTemp);
    dtostrf(humi, 6, 1, strHumi);
  }

  //hae paikallinen aika
  getTimeStr(getLocalTime());

  display.clearDisplay();
  display.setCursor(18, 48);
  display.print(strTime);
  display.setCursor(0, 0);
  display.print(strTemp);
  display.print(" C");
  display.setCursor(0, 16);
  display.print(strPres);
  display.print(" hPa");
  display.setCursor(0, 32);
  display.print(strHumi);
  display.print(" %");
  display.display();
  delay(100);
}

boolean is_Dls_On(unsigned long ut) {
  // ut = unix timestamp for current UTC time

  // Unix timestamps in the following list are UTC timestamps for daylight saving changing moments for the timezone.
  // They are intentionally one second before the full hour when the change happens
  // This list is for the Canary Islands (WET/WEST timezone). For other timezones new timestamps needs to be calculated.
  // In linux you can get these changing dates and times for a timezone with command : zdump -v timezone
  // You still need to convert the dates and times to unix timestamps but there are programs and web sites to do that.
  // Note. This list seems to be valid for whole Europe

  // check if daylight saving is on
  if (ut > 1521939599 && ut < 1540688399  ||      //25.03.18 00:59:59  28.10.18 00:59:59
      ut > 1553993999 && ut < 1572137999  ||      //31.03.19 00:59:59  27.10.19 00:59:59
      ut > 1585443599 && ut < 1603587599  ||      //29.03.20 00:59:59  25.10.20 00:59:59
      ut > 1616893199 && ut < 1635641999  ||      //28.03.21 00:59:59  31.10.21 00:59:59
      ut > 1648342799 && ut < 1667091599  ||      //27.03.22 00:59:59  30.10.22 00:59:59
      ut > 1648342799 && ut < 1667091599  ||      //27.03.22 00:59:59  30.10.22 00:59:59
      ut > 1679792399 && ut < 1698541199  ||      //26.03.23 00:59:59  29.10.23 00:59:59
      ut > 1711846799 && ut < 1729990799  ||      //31.03.24 00:59:59  27.10.24 00:59:59
      ut > 1743296399 && ut < 1761440399  ||      //30.03.25 00:59:59  26.10.25 00:59:59
      ut > 1774745999 && ut < 1792889999          //29.03.26 00:59:59  25.10.26 00:59:59
     )
  {
    return (true);
  }
  else {
    return (false);
  }
}

DateTime getUtcTime() {
  // expects that RTC time is set to UTC
  return (rtc.now());
}

DateTime getLocalTime() {
  // expects that RTC time is set to UTC
  if (is_Dls_On(rtc.now().unixtime())) {
    return (rtc.now() + TimeSpan(dls_On_Offset)); // return local summertime
  }
  else {
    return (rtc.now() + TimeSpan(dls_Off_Offset)); // return local winter time
  }
}

void getTimeStr(DateTime dt) {
  // strDate and strTime are global variables
  sprintf(strDate, "%02d.%02d.%02d", dt.day(), dt.month(), dt.year() - 2000);
  sprintf(strTime, "%02d:%02d:%02d", dt.hour(), dt.minute(), dt.second());
}

How do you know what the barometer "should" read?

For use by pilots, airports and weather stations usually report the equivalent sea level barometric pressure.

I have another barometer to compare with. And anyway the airpressure has not been here over 1032 hPa in the last three years and when this faulty one starts show readings over 1060 hPa I'm quite sure it's not working properly. And when I reboot the Arduino where the sensor is connected, it starts to show correct readings, or at least more correct readings.

The sensor seems to be working for hours correctly before it starts to show incorrect readings.

Now it is initialized in the setup() routine. I would like to know how to initialize the sensor correctly in the loop() routine without messing it up. Or without needing to reboot the whole system.

Maybe not relevant to you but I have periodic problems with BME280 modules where they will just start returning bad readings for temp/pressure/humidity but the other readings are fine.
As the sensors are battery powered in weatherproof containers it was not practical to open then up to power cycle so I added code to check if readings are valid and perform a soft reset if not.
I'm not sure if the BMP280 has soft reset but the reset code I use is below.

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);
}

Why do you believe the "other" barometer?

I'd start by writing another sketch that just reads the barometer periodically and prints the pressure to serial.

I'd also write something on my PC to grab data from the closest airport to compare against. You may find that they already provide a few days of history, so writing code may not be needed.

If the simple program fails, I'd devise some means of dropping power to the BMP280 on an hourly basis.

Thank you Riva.

I looked again around the BMP280 library and found from there a reset() function.

I added following lines to the code in the loop() routine after reading the sensor

// reset BMP280
bmp280.reset();
bmp280.initialize();
bmp280.setEnabled(0);

Sensor has 9-10 seconds time wake up after reset before it is read again. It seems to work but it has been running only one hour now. Tomorrow I will be wiser in this matter.

jremington:
Why do you believe the "other" barometer?

That notwithstanding, unless you're way below sea level an air pressure reading of 1045-1080 hPa is just wrong. So OP is quite right in saying that the readings are off.

Also air pressure normally doesn't change by 40-60 hPa within a day, maybe unless a typhoon passes over and such events are kinda hard to miss. That'd also be a pressure drop, not an increase.

Could be interference on the I2C bus or too much or too little pull-up resistance on the I2C lines causing occasional corruption. Could be lack of adequate decoupling. Could be poor quality power supply occasionally dropping out.

I've been researching BME280 data loggers for about 2 months now without any real breakthrough for a good working sketch, regardless ow what library I use. That being said, what is the rate of sampling your data? The BME280 datasheet and some of the sketches I have found change the sampling rates, sometimes by as much as 16 times! That rate is then calculated with a formula that I can't remember off the top of my head, to get a more accurate reading. Also, what is you data logger using for a power supply? Is it the 3v3 from your Arduino or off a different source. I was just thinking of stuff off the top of my head. Can you incorporate a DC power level into your sketch to track if it fluctuates along with the strange pressure readings? meaning with a date-time stamp function?

Have been running the sensor with the modified code for a few days now and it seems to be working properly.

Thank you everybody who answered

It maybe that you have a self heating problem, turning it off and on again might be curing that ?