adafruit / Adafruit_BMP280_Library

Arduino Library for BMP280 sensors
250 stars 187 forks source link

Overflow error, line 83. #57

Closed ilya7zz closed 2 years ago

ilya7zz commented 2 years ago

I use several sensors on the I2C bus. When polling every second, switching between them (call bmp.begin (0x76), bmp.begin (0x77)) after 45 minutes, a buffer overflow occurs and an error occurs, reboot.

ESP Exception Decoder Exception 29: StoreProhibited: A store referenced a page mapped with an attribute that does not permit stores PC: 0x40205c08: Adafruit_I2CDevice::Adafruit_I2CDevice(unsigned char, TwoWire*) at Memory allocation on 16 bytes failed at 0x4020250e: .../Adafruit_BMP280.cpp line 83

SCR2021-08-19 в 23 58 51

Please fix the library. file line 83:

    //i2c_dev = new Adafruit_I2CDevice(addr, _wire); // Error with buffer overflow on frequent calls bmp.begin (0x76) (c) by @badloona, AlexGyver chat.
    if (!i2c_dev) i2c_dev = new Adafruit_I2CDevice(addr, _wire);  //Temporary solution!
caternuson commented 2 years ago

Only call begin() once for each sensor in setup. There's no need to call it again to "switch" between them.

ilya7zz commented 2 years ago

It's bad that you can't call begin() multiple times. Most, seeing this flaw in the library, said that the implementation was bad and needed some work. I need to implement a task where there are many I2C devices. Everyone has different pins and different addresses. Without calling begin () again after calling Wire.begin (SDA, SCL), it is not possible to change the sensor initialization address.

An example of my code working:

void initLCD() {
  Wire.begin (SDA, SCL); //D2,D1 Выбираем дисплей
}

void getBMP1() {
  Wire.begin (14, 12); //D5,D6 Wire.begin(esda, escl);
  if (!bmp.begin(0x76)) {
    Serial.print("\nДатчик 0x76 не найден. Проверить интерфейс I2C или адрес.");
    sendNoDataLCD();
  }
  else {
    temperature = bmp.readTemperature();
    pressure_Hg = pressure * 0.0075006F; //1Па = 0.0075006168 мм рт.ст.
    sendDataLCD1();
  }
}

void getBMP2() {...}

void getBMP3() {
  Wire.begin (13, 2); //D7,D4 Wire.begin(esda, escl); где в скобках указаны пины!
  if (!bmp.begin(0x77)) Serial.println("\nДатчик 0x77 не найден. Проверить интерфейс I2C или адрес.");
  else {
    temperature = bmp.readTemperature();
    pressure_Hg = pressure * 0.0075006F; 
    sendDataLCD3();
  }
}

void getBMP4() {...}

void sendDataLCD() {
  initLCD();
  lcd.setCursor(0,0);
  lcd.print(temperature, 2);
  }
  lcd.setCursor(0,1);
  lcd.print(pressure_Hg, 1);
  lcd.print("mmHg");
}

void sendNoDataLCD() {
  initLCD();
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("  No Connected  ");
}
caternuson commented 2 years ago

I need to implement a task where there are many I2C devices.

This library supports multiple sensors. Call begin() once for each instance.

Everyone has different pins and different addresses

Why do they have different pins? Are they not all on the same I2C bus?

The example above is not complete. Where are your void setup() and void loop()?

ilya7zz commented 2 years ago

This library supports multiple sensors. Call begin() once for each instance.

If I unplug the sensor and plug it back in, it won't work! So I call begin() before every read!

Why do they have different pins? Are they not all on the same I2C bus?

Because no more than two sensors can be connected to one bus.

The example above is not complete. Where are your void setup() and void loop()?

void setup() - like everyone else.
void loop() - calls the measurement script with an interval of once per second. The project is large, it makes no sense to upload it entirely. I have shown the used construction to show that the library is not working properly.

ladyada commented 2 years ago

you have to use a multiplexor or something, what you're doing is not supported - call begin() once per sensor.

caternuson commented 2 years ago

@ilya7zz You can try the 2.4.1 release when it becomes available: https://github.com/adafruit/Adafruit_BMP280_Library/releases/tag/2.4.1 It adds the suggested basic checks for the dynamic memory allocation. Agree that doing that basic check is generally a good idea and worth adding. But no guarantee it will solve the issues for your use case.