How to make BME280 sensor and MPU6050 sensor work in same sketch with Raspberry Pi Pico W

I have made init methods for both sensors inside of their own classes, and then I tried to combine them in the same sketch. I created a custom I2C object wire to be used with the MPU6050 to stop the two sensors wires from interferring with each other but I cannot get them to both work at the same time.

void setup() {
    Serial.begin(115200);
    while (!Serial);                        

    // Initialise I2C wires
    Serial.println("Starting I2C wires...");
    // Wire.begin();
    // delay(1000);

    // Serial.println("Scanning default Wire...");    
    // i2c_scanner(Wire, "Wire (Default I2C)");
    // bme280.init();

    mpu6050.get_wire().begin();
    delay(1000);
    Serial.println("Scanning custom Wire...");
    i2c_scanner(mpu6050.get_wire(), "Wire (Custom I2C)");
    mpu6050.init();

    Wire.begin();
    delay(1000);
    Serial.println("Scanning default Wire...");    
    i2c_scanner(Wire, "Wire (Default I2C)");
    bme280.init();
}

If I call mpu6050.init() then the BME sensor will not be located and vice versa. The I2C scanner is able to detect them both but calling the init method for either sensor causes the other one to fail. Both init methods just use begin() and pass in the address and wire object. The BME init method:

void BME280::init() {
    unsigned status;
    // Wire.begin();
    status = bme.begin(0x77, &Wire);       // In case of sensor error, try address 0x77 (uint8_t)
    if (!status) {
        Serial.println("Could not locate BME280 sensor...");
        Serial.print("SensorID was: 0x"); Serial.println(bme.sensorID(),16);
        while (1) delay(10);
    }

    Serial.println("BME280 sensor initialised");   
}

The MPU init method:

void MPU6050::init() {
    // WireMPU.begin();
    if (!mpu.begin(0x68, &WireMPU, 0)) {
        Serial.println("Failed to find MPU6050 chip...");
        while (1) delay(10);
    }

    mpu.setAccelerometerRange(MPU6050_RANGE_16_G);
    mpu.setGyroRange(MPU6050_RANGE_250_DEG);
    mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
    Serial.println("MPU6050 sensor initialised");
    delay(100);
}

Output of the BME280 failing to initialise because the MPU6050 did so successfully:

Starting I2C wires...
Scanning custom Wire...
Scanning for I2C devices...
I2C device found at address 0x68
I2C scan complete

MPU6050 sensor initialised
Scanning default Wire...
Scanning for I2C devices...
I2C device found at address 0x77
I2C scan complete

Could not locate BME280 sensor...
SensorID was: 0xD0

Output of MPU6050 failing to initialise because the BME280 did so successfully:

Starting I2C wires...
Scanning default Wire...
Scanning for I2C devices...
I2C device found at address 0x77
I2C scan complete

BME280 sensor initialised
Scanning custom Wire...
Scanning for I2C devices...
I2C device found at address 0x68
I2C scan complete

Failed to find MPU6050 chip...

I know that each device works individually when I comment out either init method and leave the other one and when I do not call both init methods the I2C devices are both found as you can see above.

connected a BME280 and MPU6050 to a Raspberry Pi Pico RP2040
MPU6050 code (calls BME280 code)

// RP20040 Basic demo for accelerometer readings from Adafruit MPU6050

#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>

Adafruit_MPU6050 mpu;

void setup(void) {
  Serial.begin(115200);
  delay(2000);
  while (!Serial)
    delay(10);  // will pause Zero, Leonardo, etc until serial console opens

  Serial.println("Adafruit MPU6050 test!");
  Wire.begin();
  // Try to initialize!
  if (!mpu.begin(0x68)) {
    Serial.println("Failed to find MPU6050 chip");
    while (1) {
      delay(10);
    }
  }
  Serial.println("MPU6050 Found!");

  mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
  Serial.print("Accelerometer range set to: ");
  switch (mpu.getAccelerometerRange()) {
    case MPU6050_RANGE_2_G:
      Serial.println("+-2G");
      break;
    case MPU6050_RANGE_4_G:
      Serial.println("+-4G");
      break;
    case MPU6050_RANGE_8_G:
      Serial.println("+-8G");
      break;
    case MPU6050_RANGE_16_G:
      Serial.println("+-16G");
      break;
  }
  mpu.setGyroRange(MPU6050_RANGE_500_DEG);
  Serial.print("Gyro range set to: ");
  switch (mpu.getGyroRange()) {
    case MPU6050_RANGE_250_DEG:
      Serial.println("+- 250 deg/s");
      break;
    case MPU6050_RANGE_500_DEG:
      Serial.println("+- 500 deg/s");
      break;
    case MPU6050_RANGE_1000_DEG:
      Serial.println("+- 1000 deg/s");
      break;
    case MPU6050_RANGE_2000_DEG:
      Serial.println("+- 2000 deg/s");
      break;
  }

  mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
  Serial.print("Filter bandwidth set to: ");
  switch (mpu.getFilterBandwidth()) {
    case MPU6050_BAND_260_HZ:
      Serial.println("260 Hz");
      break;
    case MPU6050_BAND_184_HZ:
      Serial.println("184 Hz");
      break;
    case MPU6050_BAND_94_HZ:
      Serial.println("94 Hz");
      break;
    case MPU6050_BAND_44_HZ:
      Serial.println("44 Hz");
      break;
    case MPU6050_BAND_21_HZ:
      Serial.println("21 Hz");
      break;
    case MPU6050_BAND_10_HZ:
      Serial.println("10 Hz");
      break;
    case MPU6050_BAND_5_HZ:
      Serial.println("5 Hz");
      break;
  }

  Serial.println("");
  setup_BME280();
  delay(100);
}

void loop() {

  /* Get new sensor events with the readings */
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);

  /* Print out the values */
  Serial.print("Acceleration X: ");
  Serial.print(a.acceleration.x);
  Serial.print(", Y: ");
  Serial.print(a.acceleration.y);
  Serial.print(", Z: ");
  Serial.print(a.acceleration.z);
  Serial.println(" m/s^2");

  Serial.print("Rotation X: ");
  Serial.print(g.gyro.x);
  Serial.print(", Y: ");
  Serial.print(g.gyro.y);
  Serial.print(", Z: ");
  Serial.print(g.gyro.z);
  Serial.println(" rad/s");

  Serial.print("Temperature: ");
  Serial.print(temp.temperature);
  Serial.println(" degC");

  Serial.println("");
  delay(1000);
  loop_BME_280();
  delay(2000);
}

BME280 code

// BME280 sensor

// ESP8266 nodeMCU v3 GPIO5 D1 SCL GPIO4 D2 SDA
// ESP32 devkit GPIO22 SCL GPIO21 SDA
// RP2040 devkit GPIO25 SCL GPIO4 SDA

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


#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME280 bme; // I2C
//Adafruit_BME280 bme(BME_CS); // hardware SPI
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI

unsigned long delayTime;

void setup_BME280() {
  Serial.begin(115200);
  delay(2000);
  Serial.println();
  Serial.println(F("BME280 test"));

  bool status;
 
  // default settings
  // (you can also pass in a Wire library object like &Wire2)
  status = bme.begin(0x76);  
  if (!status) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }
  Serial.println("BME280 found -- Default Test --");
  delayTime = 1000;
  Serial.println();
}


void loop_BME_280() { 
  printValues();
  //delay(delayTime);
}


void printValues() {
  Serial.print("Temperature = ");
  Serial.print(bme.readTemperature());
  Serial.println(" *C");
  
  // Convert temperature to Fahrenheit
  /*Serial.print("Temperature = ");
  Serial.print(1.8 * bme.readTemperature() + 32);
  Serial.println(" *F");*/
  
  Serial.print("Pressure = ");
  Serial.print(bme.readPressure() / 100.0F);
  Serial.println(" hPa");
  
  Serial.print("Approx. Altitude = ");
  Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
  Serial.println(" m");
  
  Serial.print("Humidity = ");
  Serial.print(bme.readHumidity());
  Serial.println(" %");
  
  Serial.println();
}

serial monitor output alternately printing MPU6050 and BME280 results

Adafruit MPU6050 test!
MPU6050 Found!
Accelerometer range set to: +-8G
Gyro range set to: +- 500 deg/s
Filter bandwidth set to: 21 Hz


BME280 test
BME280 found -- Default Test --

Acceleration X: -2.09, Y: 0.19, Z: 8.16 m/s^2
Rotation X: 0.15, Y: 0.03, Z: 0.00 rad/s
Temperature: 22.55 degC

Temperature = 21.07 *C
Pressure = 1028.93 hPa
Approx. Altitude = -129.70 m
Humidity = 45.71 %

Acceleration X: -2.11, Y: 0.22, Z: 8.16 m/s^2
Rotation X: 0.15, Y: 0.03, Z: 0.00 rad/s
Temperature: 22.58 degC

Temperature = 21.07 *C
Pressure = 1028.93 hPa
Approx. Altitude = -129.72 m
Humidity = 45.66 %

Acceleration X: -8.08, Y: -1.65, Z: 3.06 m/s^2
Rotation X: -0.24, Y: -0.75, Z: -0.33 rad/s
Temperature: 22.61 degC

Temperature = 21.07 *C
Pressure = 1028.92 hPa
Approx. Altitude = -129.64 m
Humidity = 46.32 %

Acceleration X: 1.02, Y: -0.65, Z: 7.75 m/s^2
Rotation X: 0.21, Y: 1.98, Z: -0.04 rad/s
Temperature: 22.63 degC

Temperature = 21.07 *C
Pressure = 1028.94 hPa
Approx. Altitude = -129.78 m
Humidity = 46.29 %

Acceleration X: -2.15, Y: 0.29, Z: 8.19 m/s^2
Rotation X: 0.16, Y: 0.02, Z: 0.01 rad/s
Temperature: 22.66 degC

Temperature = 20.95 *C
Pressure = 1029.78 hPa
Approx. Altitude = -136.74 m
Humidity = 50.15 %

Acceleration X: -1.94, Y: 0.07, Z: 8.18 m/s^2
Rotation X: 0.12, Y: 0.08, Z: 0.05 rad/s
Temperature: 22.69 degC

I tried your code but it is still not working. The MPU sensor cannot be located unless I add in

Wire.setSDA(20);
Wire.setSCL(21);

and then change the call to mpu.begin(0x68) with if (!mpu.begin(0x68, &Wire, 0)) which then causes the BME initialisation to fail. I think it could by the way it is wired. Would you be able to provide the wiring for your sensors and Pico? Here is mine:

I think it is also worth noting that I have the new Adafruit BME280 sensor which might have different pin outs to your BME280 sensor. I am not sure about this though!

Why are you not connecting the BME280 and MPU6050 to the same I2C bus?

both devices are connected to SCL GPIO5 SDA GPIO4

I could only find one working example for the MPU with the Pico and the solution for it was to create a custom I2C object rather than using the default wire

My BME280 has got VIN, 3Vo, GND, SCK, SDO, SDI and CS. What should I connect to GPIO5 and 4 if I dont have SDA or SCL?

using different I2C busses
BME280 connected to SCL GPIO5 SDA GPIO4
MPU6050 connected to SCL GPIO19 SDA GPIO18

updated MPU6050 code (BME280 code same as post 2)

// RP20040 Basic demo for accelerometer readings from Adafruit MPU6050

#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>

// define I2C1 RP2040 pins for MPU6050
#define SDA 18
#define SCL 19

Adafruit_MPU6050 mpu;

void setup(void) {
  Serial.begin(115200);
  delay(2000);
  while (!Serial)
    delay(10);  // will pause Zero, Leonardo, etc until serial console opens

  Serial.println("\n\nAdafruit MPU6050/BME280 test!");
  Wire1.setSDA(SDA);  // setup SDA and SCL pins
  Wire1.setSCL(SCL);
  Wire1.begin();

  // Try to initialize!
  if (!mpu.begin(0x68, &Wire1, 0)) {
    Serial.println("Failed to find MPU6050 chip");
    while (1) {
      delay(10);
    }
  }
  Serial.println("MPU6050 Found!");

  mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
  Serial.print("Accelerometer range set to: ");
  switch (mpu.getAccelerometerRange()) {
    case MPU6050_RANGE_2_G:
      Serial.println("+-2G");
      break;
    case MPU6050_RANGE_4_G:
      Serial.println("+-4G");
      break;
    case MPU6050_RANGE_8_G:
      Serial.println("+-8G");
      break;
    case MPU6050_RANGE_16_G:
      Serial.println("+-16G");
      break;
  }
  mpu.setGyroRange(MPU6050_RANGE_500_DEG);
  Serial.print("Gyro range set to: ");
  switch (mpu.getGyroRange()) {
    case MPU6050_RANGE_250_DEG:
      Serial.println("+- 250 deg/s");
      break;
    case MPU6050_RANGE_500_DEG:
      Serial.println("+- 500 deg/s");
      break;
    case MPU6050_RANGE_1000_DEG:
      Serial.println("+- 1000 deg/s");
      break;
    case MPU6050_RANGE_2000_DEG:
      Serial.println("+- 2000 deg/s");
      break;
  }

  mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
  Serial.print("Filter bandwidth set to: ");
  switch (mpu.getFilterBandwidth()) {
    case MPU6050_BAND_260_HZ:
      Serial.println("260 Hz");
      break;
    case MPU6050_BAND_184_HZ:
      Serial.println("184 Hz");
      break;
    case MPU6050_BAND_94_HZ:
      Serial.println("94 Hz");
      break;
    case MPU6050_BAND_44_HZ:
      Serial.println("44 Hz");
      break;
    case MPU6050_BAND_21_HZ:
      Serial.println("21 Hz");
      break;
    case MPU6050_BAND_10_HZ:
      Serial.println("10 Hz");
      break;
    case MPU6050_BAND_5_HZ:
      Serial.println("5 Hz");
      break;
  }

  Serial.println("");
  setup_BME280();
  delay(100);
}

void loop() {

  /* Get new sensor events with the readings */
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);

  /* Print out the values */
  Serial.print("Acceleration X: ");
  Serial.print(a.acceleration.x);
  Serial.print(", Y: ");
  Serial.print(a.acceleration.y);
  Serial.print(", Z: ");
  Serial.print(a.acceleration.z);
  Serial.println(" m/s^2");

  Serial.print("Rotation X: ");
  Serial.print(g.gyro.x);
  Serial.print(", Y: ");
  Serial.print(g.gyro.y);
  Serial.print(", Z: ");
  Serial.print(g.gyro.z);
  Serial.println(" rad/s");

  Serial.print("Temperature: ");
  Serial.print(temp.temperature);
  Serial.println(" degC");

  Serial.println("");
  delay(1000);
  loop_BME_280();
  delay(2000);
}

serial output

Adafruit MPU6050/BME280 test!
MPU6050 Found!
Accelerometer range set to: +-8G
Gyro range set to: +- 500 deg/s
Filter bandwidth set to: 21 Hz


BME280 test
BME280 found -- Default Test --

Acceleration X: -1.96, Y: 0.53, Z: 8.19 m/s^2
Rotation X: 0.15, Y: 0.03, Z: 0.00 rad/s
Temperature: 22.68 degC

Temperature = 21.27 *C
Pressure = 1030.30 hPa
Approx. Altitude = -140.98 m
Humidity = 48.46 %

Acceleration X: -1.98, Y: 0.51, Z: 8.18 m/s^2
Rotation X: 0.15, Y: 0.03, Z: 0.01 rad/s
Temperature: 22.79 degC

Temperature = 21.31 *C
Pressure = 1030.32 hPa
Approx. Altitude = -141.14 m
Humidity = 48.41 %


Acceleration X: -1.95, Y: 0.52, Z: 8.19 m/s^2
Rotation X: 0.15, Y: 0.03, Z: 0.00 rad/s
Temperature: 22.93 degC

Temperature = 21.34 *C
Pressure = 1030.35 hPa
Approx. Altitude = -141.40 m
Humidity = 48.28 %

Acceleration X: -3.62, Y: -0.99, Z: 8.48 m/s^2
Rotation X: -0.46, Y: -0.21, Z: -0.17 rad/s
Temperature: 22.95 degC

Temperature = 21.35 *C
Pressure = 1030.34 hPa
Approx. Altitude = -141.33 m
Humidity = 48.83 %

Acceleration X: -4.24, Y: 8.98, Z: 0.13 m/s^2
Rotation X: 0.36, Y: 0.60, Z: 0.74 rad/s
Temperature: 22.99 degC

Temperature = 21.36 *C
Pressure = 1030.34 hPa
Approx. Altitude = -141.32 m
Humidity = 49.37 %

Acceleration X: -2.95, Y: -1.47, Z: -11.09 m/s^2
Rotation X: 0.14, Y: 0.28, Z: -0.17 rad/s
Temperature: 22.99 degC

Temperature = 21.36 *C
Pressure = 1030.31 hPa
Approx. Altitude = -141.05 m
Humidity = 49.30 %

Acceleration X: -1.70, Y: 0.65, Z: 8.32 m/s^2
Rotation X: 0.16, Y: 0.03, Z: -0.02 rad/s
Temperature: 23.01 degC

Temperature = 21.37 *C
Pressure = 1030.33 hPa
Approx. Altitude = -141.46 m
Humidity = 50.50 %


document htadafruit-bme280-humidity-barometric-pressure-temperature-sensor-breakout/pinouts specifies

  • SCK - this is also the I2C clock pin, connect to your microcontrollers I2C clock line.
  • SDI - this is also the I2C data pin, connect to your microcontrollers I2C data line.
    I assume SCK is I2C SCL and SDI is I2C SDA

Thank you so much for your help. That worked for me!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.