Adafruit BME280 library [PORTED]

Hi all,

last week I got my first Photon :grinning: and I wanted it to hook up with the (relatively new) Adafruit BME280 humidity, barometric pressure & temp sensor. Since I could not found any library working with Photon in combination with the BME280 sensor I stated looking into the Arduino Adafruit BME280 library. I ported that library to make it work with the Photon.

Adafruit BME280 library for Photon: https://github.com/mhaack/Adafruit_BME280_Library

I tested it with a the Adafruit BME280 and the Watterott BME280 (available in Germany) sensors. Both are working great. Other BME280 breakouts might work as well.

All wiring options supported by the sensor (I2C & SPI) are working with that library. For using theses see the sample app, I2C is used by default the others are commented out in the sample code. I ported the Adafruit library because it has the most flexibility in therms or wiring. If you Google you find other libraries for the BME280 sensor but most of them only support I2C protocol.

Any suggestions are welcome. :grinning:

Cheers
Markus

4 Likes

Nice job :+1:

Could you also push this library onto Particle Build (Web IDE)?

https://docs.particle.io/guide/getting-started/build/photon/#contribute-a-library

Done, available as “ADAFRUIT_BME280”.

3 Likes

Hi all,

just for the fun and because it utilizes some more features of the BME280 sensor I ported the Sparkfun BME280 library as well. It is designed for the Sparkfun BME280 breakout. Since I do not have these I used the Adafruit BME280 which works as well. The library is all read available at the Particle Build Web IDE.

Markus

3 Likes

Nice! Just got a board back the other day with a Photon hooked to a 280, and have been looking over the SF library. Will be sure to check it out. Thanks.

1 Like

@mhdevx

if you are taking on the task to update this library, adding in a constructor that allows passing the I2C address would be appreciated.

@BulldogLowell the library should be on the same version like the original Arduino library.

Defining a different I2C address is already possible. See #define BME280_ADDRESS (0x77) in Adafruit_BME280.h. You just need to define you own.

And since the address isn’t actually stored by the constructor but by bool Adafruit_BME280::begin(uint8_t addr = BME280_ADDRESS) you wouldn’t even need to #define an alternative address but only pass it instead of the default value.

Adafruit's library uses (coincidentally) the address for the device they sell.

For me, I'm downloading libraries into project files (I prefer to leave the dependancies static lest someone break its backward compatibility on a published library). Very seldom do I use Build. I was thinking about a newbie that won't know that there may be (somewhere on God's green earth) a BME280 device on another I2C address.

IMHO, with the new library 'system' and for the person simply adding in a library to their project using Build 1) having an awareness of the I2C address dependency and 2) a way to simply pass it in a constructor is beneficial. In Build, it is possible to add a library, create a program and not even see the library behind the scenes.

Even a note in the example header would be friendlier. Again this was just thoughtful consideration... not a selfish desire on my part!

1 Like

I second BulldogLowell

IMHO it is easy to understand the I2C address dependency by looking at the header file of the library. :grinning:

As written above there are strictly speaking two option of using an alternate I2C address (defining BME280_ADDRESS or passing the address via the begin method like bme.begin(0x76)).

I’m still not a friend of changing the original library to stay as much as compatible with the Arduino library.
But I enhanced the sample with some notes and an out commented sample in the code. Additionally I added a hint to the README.md. HTH.

@mhdevx, there is a way to have it both.

You could add a default/optional parameter to the constructor or have a dedicated overload that features that extra parameter.
This way you would still be 100% compatible to “legacy” code but also cater for the extra wishes.

But I agree that the already available means should suffice.
Otherwise we could even argue that we’d need more functions (e.g. uint8_t setAddress(uint8_t addr), uint8_t getAddress()) to satisfy the personal preferences of people who’d rather want to deal with the device addresses that way.

Good day sir.
Firstly thank you for porting the library, it definitely makes interfacing the sensor with the microcontroller easier.

I am new to particle and a newbie in programming microcontrollers. I have worked with the arduino uno on a few basic projects but nothing that involved I2C or SPI connections.
I need some help. Could you please direct me to a link that shows the wiring diagram you used to connect the BME280 to the particle photon for the code found in the BME adafruit library. Also i downloaded the BME280 Adafruit library but i was not able to figure out which lines of the code applied to the SPI configuration in the Void loop. This is the code i am referring to:

 #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);

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

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

void loop() {
    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();
    delay(2000);
}

@Alli
In loop() you are calling/using the methods for the object bme e.g. bme.readTemperature() returns the temperature. You have instantiated the object with Adafruit_BME280 bme(BME_CS); // hardware SPI. In this case the instance has been created for Arduino and is using the standard SPI pins. To make this work for Particle Photon - you will need to define the hardware SPI pins used on the photon (refer photon datasheets) A5 - SPI MOSI, A4 - SPI MISO, A3 - SPI SCK, A2 - SPI SS/CS. You will need to wire the module pins to these pins on the photon. I suggest you use the bme280test.ino example rather than the advancedsettings.ino and set the #define BME_CS A2 and use the hardware SPI instantiation as in the example you have posted.

Thank you for your response.
Im using the particle dev to program the controller i have made the changed you suggested and in fact i started a new project this is my code:
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#define BME_SCK A3
#define BME_MISO A4
#define BME_MOSI A5
#define BME_CS A2

#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);

void setup() {
Serial.begin(9600);
Serial.println(F(“BME280 test”));

// if (!bme.begin(0x76)) {
if (!bme.begin()) {
Serial.println(“Could not find a valid BME280 sensor, check wiring!”);
while (1);
}
}

void loop() {
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();
delay(2000);
}

but whenever i attempt to compile the program it keeps returning an error: Adafruit_Sensor.h:No such file directory. I commented it out than the it brings up the same error for the BME280.h. I can seem to figure out why.
I downloaded the Adafruit BME280 library from github and saved it in my program folder: It is in the same directory as the SRC folder. Can you please tell me what im doing wrong

@armor

I am not sure what happened but my photon is breathing green which means its unable to connect to the cloud inspite of the fact that its connected to wifi. i have been sitting with this problem for 2 hours after trying to upload the following code to the photon:

//Portable Weather Station: BME280
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#define BME_SCK A3
#define BME_MISO A4
#define BME_MOSI A5
#define BME_CS A2

#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);

void setup() {
Serial.begin(9600);
Serial.println(F(“BME280 test”));

// if (!bme.begin(0x76)) {
if (!bme.begin()) {
Serial.println(“Could not find a valid BME280 sensor, check wiring!”);
while (1);
}
}

void loop() {
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();
delay(2000);
}

Please help.

@armor
i finally found something useful on another thread.

I used the command prompt to flash the original tinker app onto the photon. The code above is not allowing the photon to connect to the cloud. I then tried uploading the same code as above with the exception of the while loop (which i commented out) but the photon is still going green and nothing appears on the serial monitor.
Also i don’t see how the pins we ascribed in this part of the code:

#define BME_SCK A3
#define BME_MISO A4
#define BME_MOSI A5
#define BME_CS A2

is associated with the rest of the code. The rest of the program does not mention these variables. I uploaded this code Do i need to add additional code to the example above to make it work?

@armor
For some reason now, after what appears to be successfully adding the adafruit bme sensor library to the project the program is returning 63 errors when compiled using the same code above. I am really not sure what is going on.

@armor @ScruffR @mhdevx
i do not mean to burden only armor with my challenges. I would greatly appreciate assistance from any anyone who is willing to assist.
Here is the image showing some of the errors that are being returned.

Why don’t you use the Web IDE? Much easier.

Create a new app - call it BME280test and save.
Click on the libraries icon, search BME280 and select the Adafruit_BME280 library.
Add library to project, confirm app.
You should now see code with the #include <Adafruit_BME280.h> at the top.
Click on the code icon and then on the library to open the files and then click on the bme280test.ino example. Copy this into your app/project.

This is what I end up with, have removed #include “Adafruit_sensors.h” as this is already in the other header.

#include <Adafruit_BME280.h>

SYSTEM_MODE(MANUAL);            //at this stage no WiFi or Cloud connection is required

#define BME_CS A2               //SPI CS pin
#define SEALEVELPRESSURE_HPA (1013.25)  //constant for altitude calculation

Adafruit_BME280 bme(BME_CS);    //instantiate object hardware SPI

void setup()
{
    Serial.begin(9600);
    Serial.println("BME280 test");
    if (!bme.begin()) {Serial.println("Could not find a valid BME280 sensor, check wiring!"); while (1);}   //bme object could not be initialised
}
// Check and print values and wait/delay for 2 seconds
void loop()
{
    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();
    delay(2000);
}

This compiled but I haven’t flashed it to a device. Once you do that the device will go offline because of the SYSTEM_MODE(MANUAL);

@armor
Thank you, the WEB IDE is much easier. Thank you i followed your instructions and copied the following code into my project:

#include "Adafruit_Sensor.h"
#include "Adafruit_BME280.h"

#define BME_SCK D4
#define BME_MISO D3
#define BME_MOSI D2
#define BME_CS D5

#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);

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

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

void loop() {
    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();
    delay(2000);
}

The above code compiled in the web ide will try to flash it to my photon later today, thank you again.

But how did you end up with the code you showed above?
Since you added this code to the project
SYSTEM_MODE(MANUAL);
do i need to remove it before i flash the code to the project?
Also why did you remove the following:
#define BME_SCK
#define BME_MISO
#define BME_MOSI