1

I'm going crazy trying to understand some strange reads from BME280 sensor.

With this code:

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

#define SAMPLES_NUM             100
#define SAMPLES_OFF             256

#define GRAPH_X                 (SCREEN_WIDTH - (SAMPLES_NUM + 1))
#define GRAPH_Y                 16
#define GRAPH_W                 (SAMPLES_NUM + 1)
#define GRAPH_H                 47
#define DATA_X                  10
#define DATA_Y                  0

#define SEALEVELPRESSURE_HPA    1000
#define PRESSURE_HPA_MIN        980
#define PRESSURE_HPA_MAX        1045

TwoWire Wire1(PB9, PB8);
TwoWire Wire2(PB11, PB10);
Adafruit_SSD1306 *display;
Adafruit_BME280 *bme;

void setup() {
  pinMode(PC13, OUTPUT);
  digitalWrite(PC13, LOW);

  delay(500);

  Wire1.begin();
  Wire1.setClock(400000);

  Wire2.begin();
  Wire2.setClock(400000);

  delay(100);

  display = new Adafruit_SSD1306(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire2);
  bme = new Adafruit_BME280();

  while (!display->begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    delay(500);
  }

  delay(500);

  display->clearDisplay();
  display->dim(0);
  display->setTextSize(1);
  display->setTextColor(WHITE);
  display->setCursor(0, 0);
  display->println("Display initialized");
  display->display();

  int b = 0;
  display->println("init bme...");
  while (b == 0) {
    b = bme->begin(BME280_ADDRESS_ALTERNATE, &Wire1);
    display->print("b=");
    display->print(b);
    display->print("; ");
    display->display();
  }
  display->println();
  display->display();

  if (b == 1) {
    bme->setSampling(Adafruit_BME280::MODE_FORCED,
                    Adafruit_BME280::SAMPLING_X1, // temperature
                    Adafruit_BME280::SAMPLING_X1, // pressure
                    Adafruit_BME280::SAMPLING_X1, // humidity
                    Adafruit_BME280::FILTER_OFF);
  }
  delay(5000);
}

void loop() {
//  bme->takeForcedMeasurement();
  float _t1 = bme->readTemperature();
  float _h1 = bme->readHumidity();
  float _p1 = (bme->readPressure() / ((float)100.0F));

  display->clearDisplay();
  display->setCursor(0, 0);

  display->print("T  : ");
  display->print(_t1, 1);
  display->print((char)247);
  display->println("C");

  display->print("RH : ");
  display->print(_h1, 1);
  display->println("%");

  display->print("P  : ");
  display->print(_p1, 1);
  display->println("hPa");

  display->display();

  delay(5000);
}

And if I uncomment // bme->takeForcedMeasurement(); it wait forever.

I get an obviously erroneous read:

T  : 66.1°C
RH : 100.0%
P  : -1599.7hPa

With this code:

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

TwoWire Wire1(PB9, PB8);
TwoWire Wire2(PB11, PB10);
Adafruit_SSD1306 *display;
Adafruit_BME280 *bme;

void setup() {
  pinMode(PC13, OUTPUT);
  digitalWrite(PC13, LOW);

  delay(500);

  Wire1.begin();
  Wire1.setClock(400000);

  Wire2.begin();
  Wire2.setClock(400000);

  delay(100);

  display = new Adafruit_SSD1306(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire2);
  bme = new Adafruit_BME280();

  while (!display->begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    delay(500);
  }

  delay(500);

  display->clearDisplay();
  display->dim(0);
  display->setTextSize(1);
  display->setTextColor(WHITE);
  display->setCursor(0, 0);
  display->println("Display initialized");
  display->display();

  int b = 0;
  display->println("init bme...");
  while (b == 0) {
    b = bme->begin(BME280_ADDRESS_ALTERNATE, &Wire1);
    display->print("b=");
    display->print(b);
    display->print("; ");
    display->display();
  }
  display->println();
  display->display();

  if (b == 1) {
    bme->setSampling(Adafruit_BME280::MODE_FORCED,
                    Adafruit_BME280::SAMPLING_X1, // temperature
                    Adafruit_BME280::SAMPLING_X1, // pressure
                    Adafruit_BME280::SAMPLING_X1, // humidity
                    Adafruit_BME280::FILTER_OFF);
  }
  delay(5000);
}

void loop() {
  bme->takeForcedMeasurement();
  float _t1 = bme->readTemperature();
  float _h1 = bme->readHumidity();
  float _p1 = (bme->readPressure() / ((float)100.0F));

  display->clearDisplay();
  display->setCursor(0, 0);
  display->println(_t1, 1);
  display->println(_h1, 1);
  display->println(_p1, 1);

  display->display();

  delay(5000);
}

I get perfect read:

24.5
45.7
1009.8

I can't understand the problem. Wiring it's ok and I can detect on both I2C bus devices address with i2cscanner.

GinoC
  • 111
  • 1
  • Your question isn't clear: when you uncomment that line, does it wait forever or do you get an erroneous read? What else is different between the 2 sketches? – SoreDakeNoKoto May 10 '20 at 15:01
  • Sorry sorry if i wasn't clear enough. However if I uncomment it wait forever, otherwise it take erroneous reads. However, I tried, if I change some print, for example a `display->print("Temperature:");` before `display->println(_t1, 1);` , reads changes systematically. It seems like a stack overflow or a memory bad allocation, or something like that... – GinoC May 11 '20 at 00:24
  • So basically, if you uncomment that function call, the code waits forever (where does it "wait" exactly? Within the `takeForcedMeasurement()`? Find out exactly where.). But if you leave the line commented out, you get wrong values. And aside from this, you get unstable behaviour just from changing the `Serial.print()` statements. Like you said, this is possibly some issue with memory. Is there a reason you're allocating `display` and `bme` on the heap? Take them out of `setup()` and declare them statically in file scope, then see if anything changes. – SoreDakeNoKoto May 11 '20 at 23:02
  • Yes I tried to declare statically and is not that the problem. I think it wait forever on `takeForcedMeasurement()` because the same problem, and it not get the reply and wait forever for it. – GinoC May 12 '20 at 07:13
  • That's a different issue from the strange behaviour you observed. Does changing the `Serial.print()` strings still affect the execution? – SoreDakeNoKoto May 13 '20 at 01:03

0 Answers0