[SOLVED] I2C-BME280/BMP280 works with bmp.begin(0x76,0x58)

Hi everybody,

Edit: 02.01.2021 10:33 **
finally got the sensor working. The BME280 turned out to be a BM
P**280
So with a BMP280-library from adafruit and with a modified call of the begin-method

bmp.begin(0x76,0x58)) { // I2C-adress , Chip-ID

I was able to read the sensor data.

original post:
I'm testing a BME280-I2C-Sensor with a ESP8266-Wemos D1 Mini-board.
As a first test I used this democode from adafruit

/***************************************************************************
  This is a library for the BME280 humidity, temperature & pressure sensor

  Designed specifically to work with the Adafruit BME280 Breakout
  ----> http://www.adafruit.com/products/2650

  These sensors use I2C or SPI to communicate, 2 or 4 pins are required
  to interface. The device's I2C address is either 0x76 or 0x77.

  Adafruit invests time and resources providing this open source code,
  please support Adafruit andopen-source hardware by purchasing products
  from Adafruit!

  Written by Limor Fried & Kevin Townsend for Adafruit Industries.
  BSD license, all text above must be included in any redistribution
  See the LICENSE file for details.
 ***************************************************************************/

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

#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10

#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() {
    Serial.begin(9600);
    while(!Serial);    // time to get serial running
    Serial.println(F("BME280 test"));

    unsigned status;
    
    // default settings
    status = bme.begin(0x76);  //status = bme.begin();
    // You can also pass in a Wire library object like &Wire2
    // status = bme.begin(0x76, &Wire2)
    if (!status) {
        Serial.println("Could not find a valid BME280 sensor, check wiring, address, sensor ID!");
        Serial.print("SensorID was: 0x"); Serial.println(bme.sensorID(),16);
        Serial.print("        ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n");
        Serial.print("   ID of 0x56-0x58 represents a BMP 280,\n");
        Serial.print("        ID of 0x60 represents a BME 280.\n");
        Serial.print("        ID of 0x61 represents a BME 680.\n");
        while (1) delay(10);
    }
    
    Serial.println("-- Default Test --");
    delayTime = 1000;

    Serial.println();
}


void loop() { 
    printValues();
    delay(delayTime);
}


void printValues() {
    Serial.print("Temperature = ");
    Serial.print(bme.readTemperature());
    Serial.println(" *C");

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

in the serial monitor I get this as result

23:17:42.804 -> Could not find a valid BME280 sensor, check wiring, address, sensor ID!
23:17:42.898 -> SensorID was: 0x58
23:17:42.945 ->         ID of 0xFF probably means a bad address, a BMP 180 or BMP 085
23:17:42.992 ->    ID of 0x56-0x58 represents a BMP 280,
23:17:43.039 ->         ID of 0x60 represents a BME 280.
23:17:43.086 ->         ID of 0x61 represents a BME 680.

So I connected a logic-analyser to look and decode the bitbanging in the I2C-Bus

THe result of the logic analyser shows that the request with I2C-Adress results in an ACK
Adresswrite gets an ACK
Datawrite gets an ACK
ADressread gets an ACK
Dataread works but and retrieves a 0x58 but I get a NACK
The "N" in the protocol-anaylser.
I'm not familiar with th ebitbanging details of the I2C-Bus.
see attached picture.

Does anybody know what the reason could be that reading the sensordata does not work?

best regards Stefan

Start with something simple, that is of course a I2C Scanner sketch.
Could you increase the sample rate to 4 MHz or more ? I can not see a START or STOP condition on the bus.

Can you give a link to your BME280 module ? (a link to where you bought it).
It is possible that they used a pcb board for the BME280 and put another sensor on it.

Adding a delay between the Wire functions might help. It is hard to see which clock pulse belongs to what.

Why is there not a START condition "S" at the beginning ?

If the PulseView decoding is correct, then the Slave acknowledges to 0x76 for reading and writing.

When the Master reads data, then the Master puts a NACK on the I2C bus after the last data has been read. That is correct and according to the I2C standard. The Master determines how many data will be read and it tells the Slave that no more data is required. After that the Master sends a STOP.

The Master does not tell the Slave that the databyte has been received and acknowledges that to the Slave, because the Slave does not care at all. The Master controls everything. The ACK by the Master after a databyte could be called "pulse to tell the Slave that it should set a new byte ready in its shift-out register and increment the internal register pointer". After the last databyte, that pulse it not needed.

If everything is correct and the Adafruit library reads and shows the ID from the sensor, does that mean that you have a BMP280 ? A real BMP280 or a counterfeit ?

How much RAM does your board have? From what I recall those 680s need a bunch.

-jim lee

Are you using a module which includes I2C pull-up resistors?
It seems the logic analyser has found the correct address 0x76.

Hi Koepel,

here is the link to the BME280-Board
https://www.komputer.de/zen/index.php?main_page=product_info&cPath=43_44&products_id=497&zenid=c9nk2irfjrqfv7e5986iphenh0

I recorded the bitbanging at 8 MHz and attached the sigrok-files as a ZIP-file.
If you have th esoftware pulseview you can zoom in in the original data for a more detailed analysis.
I attached screenshots an overview of the whole communication and a zoom-in at the Start-Condition.

The I2C-scanner says
I2C-device found at adress 0x76.

The supply-voltage comes from the ESP8266 board and is 3,26V
An ESP8266-board has 64 kB RAM so this really should be enough for a BME280-sensor (not a BME680)

BME280-8MHz.zip (1.56 KB)

Very nice pictures. I was also able to open the sigrok session files. Everything looks fine. So all is well and nothing is wrong.

Well, the only thing is that they sold you a BMP280, same as here: https://forum.arduino.cc/index.php?topic=638023.0.

Try this format of the begin statement:
status = bme.begin();
Without supplying an address.

It appears to have responded to you original begin statement with:
23:17:42.898 -> SensorID was: 0x58

The behavior could be how it responds to this conflict in IDs.

Hi 6v6,

I don't understand what you mean by

It appears to have responded to you original begin statement with:
23:17:42.898 -> SensorID was: 0x58

The behavior could be how it responds to this conflict in IDs.

best regards Stefan

Ok. It wasn’t very clear.

There is an alternative to this form the begin method which you have used:
status = bme.begin(0x76);

That alternative is:
status = bme.begin();

But, likely is, as has been pointed out, the device you have obtained is not directly compatible with the adafruit library.

Hi everybody,

@6v6 as you mentioned the ID 58 I was thinking new about it.
ID 58 indicates a BMP280 (instead of a BME280).

So I tried a demo-code from Adafruit that is written for BMP280-Sensors

The BMP-class has a begin-method that accepts two parameters
I2C-adress and Sensor-ID

bool Adafruit_BMP280::begin(uint8_t addr, uint8_t chipid) {
  _i2caddr = addr;

So I adapted the demo-code to this adress and sensor-ID

  //if (!bmp.begin()) {
  if (!bmp.begin(0x76,0x58)) {

and now I can read the sensordata successfully

10:12:51.669 -> Temperature = 21.71 *C
10:12:51.669 -> Pressure = 980.23 hPa
10:12:51.716 -> Approx altitude = 331.48 m

here is the demo-code

/* This code is to use with Adafruit BMP280           (Metric)
 * It measures both temperature and pressure and it displays them on the Serial monitor with the altitude
 * It's a modified version of the Adafruit example code
 * Refer to www.surtrtech.com or SurtrTech Youtube channel
 */

#include <Adafruit_BMP280.h>

Adafruit_BMP280 bmp; // I2C Interface

void setup() {
  Serial.begin(9600);
  Serial.println(F("BMP280 test"));

  //if (!bmp.begin()) {
  if (!bmp.begin(0x76,0x58)) {
    Serial.println(F("Could not find a valid BMP280 sensor, check wiring!"));
    while (1);
  }

  /* Default settings from datasheet. */
  bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,     /* Operating Mode. */
                  Adafruit_BMP280::SAMPLING_X2,     /* Temp. oversampling */
                  Adafruit_BMP280::SAMPLING_X16,    /* Pressure oversampling */
                  Adafruit_BMP280::FILTER_X16,      /* Filtering. */
                  Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */
}

void loop() {
    Serial.print(F("Temperature = "));
    Serial.print(bmp.readTemperature());
    Serial.println(" *C");

    Serial.print(F("Pressure = "));
    Serial.print(bmp.readPressure()/100); //displaying the Pressure in hPa, you can change the unit
    Serial.println(" hPa");

    Serial.print(F("Approx altitude = "));
    Serial.print(bmp.readAltitude(1019.66)); //The "1019.66" is the pressure(hPa) at sea level in day in your region
    Serial.println(" m");                    //If you don't know it, modify it until you get your current altitude

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

best regards Stefan

I don't know how much difference there is between a BMP280 and a BME280.

might be that the communication is the same. On the BMP280th ehm the BME280 ehm the sensor-board is printed
GY-BM___E / P___

Where the "" is a small white square. ANd If I look very closely I can see a tiny dot of black ink in the P-square.

So I guess this supertiny dot of black ink shall indicate it is a BMP280 sensor.
And as an additional comment: What is so hard about writing a demo-code that does the scanning and then adapts the I2C-adress and Chip-ID to what is found and then trying to read?

or at least a demo-code that has a comment use BMP/BME-Scanner to retrieve I2C-Adress and Chip-ID
then adapt call to

if (!bmp.begin(yourI2C-adress,your chip-ID)) {  // example bmp.begin(0x76,0x58)

best regards Stefan

Edit: here is the picture from the online-shop. two letters where not readable on the picture.
So I editied them with the pale yellow color.

Komputer_de-BMP-Sensor-Board-bottomview.png

Komputer_de-BMP-Sensor-Board-bottomview.png