Help with BMP388 in I2C mode

Hi everyone, I'm having some difficulty interfacing with a BMP388 (a CJMCU-388 clone to be precise) pressure sensor. I can't get the sensor to show up in I2C or SPI mode.

Connections
For I2C, the connections I made are identical to that in the Adafruit tutorial, like this:

Later, I also tried SPI mode, in which case the wiring was as follows:
https://learn.adafruit.com/assets/96908

Code
I tried running the basic Adafruit BMP3XX code in I2C mode:

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BMP3XX.h"

#define BMP_SCK 13
#define BMP_MISO 12
#define BMP_MOSI 11
#define BMP_CS 10

#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BMP3XX bmp;

void setup() {
  Serial.begin(115200);
  while (!Serial);
  Serial.println("Adafruit BMP388 / BMP390 test");

  if (!bmp.begin_I2C()) {   // hardware I2C mode, can pass in address & alt Wire
  //if (! bmp.begin_SPI(BMP_CS)) {  // hardware SPI mode  
  //if (! bmp.begin_SPI(BMP_CS, BMP_SCK, BMP_MISO, BMP_MOSI)) {  // software SPI mode
    Serial.println("Could not find a valid BMP3 sensor, check wiring!");
    while (1);
  }

  // Set up oversampling and filter initialization
  bmp.setTemperatureOversampling(BMP3_OVERSAMPLING_8X);
  bmp.setPressureOversampling(BMP3_OVERSAMPLING_4X);
  bmp.setIIRFilterCoeff(BMP3_IIR_FILTER_COEFF_3);
  bmp.setOutputDataRate(BMP3_ODR_50_HZ);
}

void loop() {
  if (! bmp.performReading()) {
    Serial.println("Failed to perform reading :(");
    return;
  }
  Serial.print("Temperature = ");
  Serial.print(bmp.temperature);
  Serial.println(" *C");

  Serial.print("Pressure = ");
  Serial.print(bmp.pressure / 100.0);
  Serial.println(" hPa");

  Serial.print("Approx. Altitude = ");
  Serial.print(bmp.readAltitude(SEALEVELPRESSURE_HPA));
  Serial.println(" m");

  Serial.println();
  delay(2000);
}

and SPI mode:

```#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BMP3XX.h"

#define BMP_SCK 13
#define BMP_MISO 12
#define BMP_MOSI 11
#define BMP_CS 10

#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BMP3XX bmp;

void setup() {
  Serial.begin(115200);
  while (!Serial);
  Serial.println("Adafruit BMP388 / BMP390 test");

  //if (!bmp.begin_I2C()) {   // hardware I2C mode, can pass in address & alt Wire
  if (! bmp.begin_SPI(BMP_CS)) {  // hardware SPI mode  
  //if (! bmp.begin_SPI(BMP_CS, BMP_SCK, BMP_MISO, BMP_MOSI)) {  // software SPI mode
    Serial.println("Could not find a valid BMP3 sensor, check wiring!");
    while (1);
  }

  // Set up oversampling and filter initialization
  bmp.setTemperatureOversampling(BMP3_OVERSAMPLING_8X);
  bmp.setPressureOversampling(BMP3_OVERSAMPLING_4X);
  bmp.setIIRFilterCoeff(BMP3_IIR_FILTER_COEFF_3);
  bmp.setOutputDataRate(BMP3_ODR_50_HZ);
}

void loop() {
  if (! bmp.performReading()) {
    Serial.println("Failed to perform reading :(");
    return;
  }
  Serial.print("Temperature = ");
  Serial.print(bmp.temperature);
  Serial.println(" *C");

  Serial.print("Pressure = ");
  Serial.print(bmp.pressure / 100.0);
  Serial.println(" hPa");

  Serial.print("Approx. Altitude = ");
  Serial.print(bmp.readAltitude(SEALEVELPRESSURE_HPA));
  Serial.println(" m");

  Serial.println();
  delay(2000);
}

In both cases, I got the "Could not find a valid BMP3 sensor, check wiring!" message. I also tried running an I2C scanner to detect any I2C addresses, but my sensor was not detected:

#include <Wire.h>

void setup() {
  Wire.begin();

  Serial.begin(9600);
  while (!Serial); // Leonardo: wait for Serial Monitor
  Serial.println("\nI2C Scanner");
}

void loop() {
  int nDevices = 0;

  Serial.println("Scanning...");

  for (byte address = 1; address < 127; ++address) {
    // The i2c_scanner uses the return value of
    // the Wire.endTransmission to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    byte error = Wire.endTransmission();

    if (error == 0) {
      Serial.print("I2C device found at address 0x");
      if (address < 16) {
        Serial.print("0");
      }
      Serial.print(address, HEX);
      Serial.println("  !");

      ++nDevices;
    } else if (error == 4) {
      Serial.print("Unknown error at address 0x");
      if (address < 16) {
        Serial.print("0");
      }
      Serial.println(address, HEX);
    }
  }
  if (nDevices == 0) {
    Serial.println("No I2C devices found\n");
  } else {
    Serial.println("done\n");
  }
  delay(5000); // Wait 5 seconds for next scan
}

What I do know is that the 5V to 3.3V voltage regulator on the breakout board is at least functional. Is there any more debugging I can do (without an oscilloscope sadly), or is this the end of the road for my BMP388? Any advice is very welcome.

This indicates to me a 3.3V board that may not work without level shifters with a 5V controller.

Did you check the I2C pullup resistors? Do you know what that means?

After reading your comment, I tried putting two 4.7kOhm resistors pulling up both SCK and SDI/SDA to 5V, however, the I2C scanner still fails to detect the sensor.

Hard to say what might be wrong. I always order at least two of each module so that swapping modules can help to detect faulty (killed...) modules. A scope and logic analyzer also can be very helpful.

1 Like

document BMP388 pinout states
pins going into the breakout have level shifting circuitry to make them 3-5V logic level safe. Use whatever logic level is on Vin!

also BMP388 schematic shows pullups on SCL and SDA

the circuit of post #1 should work
what are the voltage levels on the SDA and SCL pins?
if you have an oscilloscope look at the SDA and SLC signals

Upload the following I2C Scanner Program to find the Slave Address of your sensor.

#include <Wire.h>

void setup()
{
  Serial.begin(9600);
  Serial.println("I2C search");
  Serial.println("-------------------------");

  Wire.begin();
  int i2c = 0b0000000;
  for (int i = 0; i < 127; i++)
  {
    Serial.print("Search at [");
    Serial.print(i2c, HEX);
    Serial.print("]: ");
    Wire.beginTransmission(i2c);
    byte busStatus = Wire.endTransmission();
    if (busStatus == 0)
    {
      Serial.println("FOUND!");
      while(1);
    }
    else
    {
      Serial.println("not found");
    }
    i2c++;
  }
}

void loop() {}

The following schematic of BMP388/390 shows that the breakout board is equipped with I2C Bus pull-up resistors, 3.3v/5V level sifters, and 5/3.3V voltage regulator.

what are the voltage levels on the SDA and SCL pins?

Both are 5V, as measured with a multimeter.

Upload the following I2C Scanner Program to find the Slave Address of your sensor.

I ran that program but found no I2C devices for any of the possible addresses. I'm inclined to believe this particular sensor is a dud, given that there is no reported I2C address.

Check the continuity of the jumper wires and also for the good contacts with the breadboard. Before discarding the sensor, take it out from the breadboard and make a direct connection with the UNO.

have you any other I2C sensors you can attach just to test the scanner, wire libraries, etc are working on your system OK

Check the continuity of the jumper wires and also for the good contacts with the breadboard. Before discarding the sensor, take it out from the breadboard and make a direct connection with the UNO.

I've confirmed that the jumper wires have no breaks, and for kicks, I also confirmed that the pins weren't shorted on the sensor. Direct connection between the sensor and the UNO also bore no fruit.

have you any other I2C sensors you can attach just to test the scanner, wire libraries, etc are working on your system OK

I was able to successfully connect 2 UNOs using I2C and have them pass data, so I'm assuming the problem is local to the sensor.

1 Like

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