This guide shows how to use the BME280 sensor module with Arduino to read pressure, temperature, humidity and estimate altitude. We’ll show you how to wire the sensor, install the required libraries, and write a simple sketch to display the sensor readings.
You might also like reading other BME280 guides:
- ESP32 with BME280 Sensor using Arduino IDE
- ESP32 Web Server with BME280 – Weather Station
- ESP8266 with BME280 using Arduino IDE
- ESP32/ESP8266 with BME280 using MicroPython
Introducing BME280 Sensor Module
The BME280 sensor module reads barometric pressure, temperature, and humidity. Because pressure changes with altitude, you can also estimate altitude. There are several versions of this sensor module. The BME280 sensor uses I2C or SPI communication protocol to exchange data with a microcontroller.
We’re using the module illustrated in the figure below.
This sensor communicates using I2C communication protocol, so the wiring is very simple. You connect the BME280 sensor to the Arduino Uno I2C pins as shown in the table below:
BME280 | Arduino |
Vin | 5V |
GND | GND |
SCL | A5 |
SDA | A4 |
There are other versions of this sensor that can use either SPI or I2C communication protocols, like the module shown in the next figure:
If you’re using one of these sensors, to use I2C communication protocol, use the following pins:
BME280 | Arduino |
SCK (SCL Pin) | A5 |
SDI (SDA pin) | A4 |
If you use SPI communication protocol, you need to use the following pins:
BME280 | Arduino |
SCK (SPI Clock) | Pin 13 |
SDO (MISO) | Pin 12 |
SDI (MOSI) | Pin 11 |
CS (Chip Select) | Pin 10 |
Parts Required
To complete this tutorial you need the following parts:
You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!
Schematic
Wire the BME280 sensor to your Arduino board as shown in the following schematic diagram.
Installing the BME280 library
To get readings from the BME280 sensor module you need to use the Adafruit_BME280 library. Follow the next steps to install the library in your Arduino IDE:
Open your Arduino IDE and go to Sketch > Include Library > Manage Libraries. The Library Manager should open.
Search for “adafruit bme280 ” on the Search box and install the library.
Installing the Adafruit_Sensor library
To use the BME280 library, you also need to install the Adafruit_Sensor library. Follow the next steps to install the library in your Arduino IDE:
Go to Sketch > Include Library > Manage Libraries and type “Adafruit Unified Sensor” in the search box. Scroll all the way down to find the library and install it.
After installing the libraries, restart your Arduino IDE.
Reading Pressure, Temperature, and Humidity
To read pressure, temperature, and humidity we’ll use a sketch example from the library.
After installing the BME280 library, and the Adafruit_Sensor library, open the Arduino IDE and, go to File > Examples > Adafruit BME280 library > bme280 test.
/*
* Complete Project Details https://randomnerdtutorials.com
*/
#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);
Serial.println(F("BME280 test"));
bool status;
// default settings
// (you can also pass in a Wire library object like &Wire2)
status = bme.begin();
if (!status) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
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");
// 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();
}
How the Code Works
Continue reading this section to learn how the code works, or skip to the “Demonstration” section.
Libraries
The code starts by including the needed libraries: the wire library to use I2C, and the Adafruit_Sensor and Adafruit_BME280 libraries to interface with the BME280 sensor.
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
SPI communication
As we’re going to use I2C communication, the following lines that define the SPI pins are commented:
/*#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10*/
Sea level pressure
A variable called SEALEVELPRESSURE_HPA is created.
#define SEALEVELPRESSURE_HPA (1013.25)
This variable saves the pressure at the sea level in hectopascal (is equivalent to milibar). This variable is used to estimate the altitude for a given pressure by comparing it with the sea level pressure. This example uses the default value, but for more accurate results, replace the value with the current sea level pressure at your location.
I2C
This example uses I2C communication protocol by default. As you can see, you just need to create an Adafruit_BME280 object called bme.
Adafruit_BME280 bme; // I2C
To use SPI, you need to comment this previous line and uncomment one of the following lines.
//Adafruit_BME280 bme(BME_CS); // hardware SPI
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI
setup()
In the setup(), start a serial communication:
Serial.begin(9600);
And the sensor is initialized:
status = bme.begin();
if (!status) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
Note: when testing the sensor, if you can’t get any sensor readings, you may need to find your BME280 sensor I2C address. With the BME280 wired to your Arduino, run this I2C scanner sketch to check the address of your sensor. Then, pass the address to the begin() method.
Printing values
In the loop(), the printValues() function reads the values from the BME280 and prints the results in the Serial Monitor.
void loop() {
printValues();
delay(delayTime);
}
Reading temperature, humidity, pressure, and estimate altitude is as simple as using the following methods on the bme object:
- bme.readTemperature() – reads temperature in Celsius;
- bme.readHumidity() – reads absolute humidity;
- bme.readPressure() – reads pressure in hPa (hectoPascal = millibar);
- bme.readAltitude(SEALEVELPRESSURE_HPA) – estimates altitude in meters based on the pressure at the sea level.
Demonstration
Upload the code to your Arduino Board.
Open the Serial Monitor at a baud rate of 9600.
You should see the readings displayed on the Serial Monitor.
Wrapping Up
The BME280 provides an easy and inexpensive way to get pressure, temperature and humidity readings. The sensor communicates via I2C communication protocol, which means that wiring is very simple, you just need to connect the sensor to the Arduino I2C pins.
Writing the code to get the sensor readings is also very straightforward thanks to the BME280_Adafruit library. You just need to use the readTemperature(), readHumidity() and readPressure() methods. You can also estimate altitude using the readAltitude() method.
We have guides for other sensors and modules with the Arduino that you may find useful:
- DHT11/DHT22 Humidity and Temperature Sensor With Arduino
- DS18B20 Temperature Sensor with Arduino
- I2C OLED Display with Arduino
- Relay Module with Arduino
- Ultrasonic Sensor HC-SR04 with Arduino
If you want to learn more about Arduino, take a look at our resources:
Thanks for reading.
Would be great to see this BME280 on an ESP 01 for outdoor and read to your mobile device or better to another indoor ESP8266 with LCD 🙂 Thanks for the great work. You guys are awesome. Thumbs up!
Thank you.
We’re preparing a guide for the BME280 with ESP8266. So, stay tuned 😀
Hello; Really like this tutorial. One thing you might consider is: obtaining the sealevel pressure from the web as this changes frequently. here is an example of a link to the information: “https://api.weather.gov/stations/KTLH/observations/latest?require_qc=true”
This returns a json table with the data in it. I’m working on this and having trouble parsing the table. Maybe you can figure this out. The link above is just one example provoded by the State of Florida. Maybe other States have similar services.
Excellent article. There is a similar Bosch sensor called the BMP280 which has Pressure/Temperature but does not include humidity. Many ebay sellers confuse the two and sell the BMP280 as the BME280. There are 3 ways to identify the BME280 :
1. Shape – the metal BME sensor is square; the BMP is rectangular.
2. Location of Vent Hole – On LHS for BME; or RHS for BMP.
3. Code – the BME has P in the code marking; the BMP has K in the code.
Also, the BME boards are often 3-4 times the price of the BMP boards.
To avoid frustration, check that the sensor you have bought is the BME280 and not the BMP280.
Hi.
Thank you so much for sharing that info.
It might save hours of frustration.
Regards,
Sara
Dang.. now I have to go check which chip is on my breakout boards and my return window has already passed.. That will serve me right for not checking properly!
Additionally, the BMP280 restricts what you can calculate, whilethe BME280 allows you to calculate dew point and humidex (feels like) temperatures. I bought BME280s from Amazon and received BMP280s instead. Had one soldered in place before I discovered the issue. Wish the boards were marked clearly.
It would be useful to know how to find the current sea level air pressure for a location.
Hoe do I do it?
Duncan, You need the qnh value for your nearest aerodrome
Here is mine (1015hpa)
skybrary.aero/index.php/EGNX
My point was that Rui should show a method in the tutorial, not just leave it hanging in mid air…
Thanks
Hi Duncam.
I think it depends on where you live.
Here in Portugal, I cant get the pressure from IPMA website (portuguese meteorology website).
Try searching your country + sea level pressure on google and see the results.
Regards,
Sara
I believe from my flight tutorials (when I was paying attention) that the air pressure at sea level is standardised since the amount of air above the sea (and that’s the sea as in the ocean!) is broadly similar no matter where we are on the planet.
29.92 inches of Hg or 1013.25 hectopascals in real money.
I should add that this varies throughout the year but standard air pressure is often close enough. I can’t find a way to edit my comment (sorry for the D’OH).
Local weather stations generally keep a calibrated ASL pressure in case you need to calibrate. Of course, you can also calibrate your sensor by going to the seaside or if you know your height ASL you can do it in reverse.
Thank you so much for sharing your knowledge about this.
Regards,
Sara
Interesting post.
With the BME280 it is important to realise that by default it is in automode, taking continuous readings. This will warm up the chip, affecting the read temperature.
It is better to use the BME in “Forced mode” and to set the sampling rate:
bme.setSampling(Adafruit_BME280::MODE_FORCED,
Adafruit_BME280::SAMPLING_X1, // temperature
Adafruit_BME280::SAMPLING_X1, // pressure
Adafruit_BME280::SAMPLING_X1, // humidity
Adafruit_BME280::FILTER_OFF );
I had to add this specification to have to work with this sensor
status = bme.begin(0x76);
These little tweaks give you a a lot of frustration!
Thanks for sharing your experience.
Nice tips there. I’m moving my code from a DHT22 so that will save me hours of frustration!
Hi Sara and Rui,
What to do if I want to use BME280 twice.
For my greenhouse I want to know T and RH outside and inside.
Is that possible anyway?
Cheers
Gerard
Hi Gerard.
Can you provide more details?
Do you want to wire the BME280 to the same board? Read this guide to learn how to interface multiple I2C devices: https://randomnerdtutorials.com/esp32-i2c-communication-arduino-ide/
If you want to use different boards, you can read this article to learn how to send BME280 sensor readings from one board to the other: https://randomnerdtutorials.com/esp32-client-server-wi-fi/
Regards,
Sara
Wow, thank you for the quick reply Sara.
Preferably I use one board but two BME280 connected to it
I will have a look at the guide and be back in case I run into problems.
Thank you so much
Cheers,
Gerard
bluedot.space/tutorials/connect-two-bme280-on-i2c-bus/ refers to the BME280 specifically.
Thank you Duncan, that is exactly what I was looking for.
Cheers,
Gerard
Hi Sara,
I followed the instructions as suggested by Duncan (see below)
In the sketch as in this tutorial BlueDot_BME280.h was included instead of Wire.h It runs like clockwork
Kind regards,
Gerard
below >> above
I have a remote debugger via telnet being used in my setup. But when my dme.begin is called and it can’t find or has a problem with my dme280, it reboots. Is there a way to not make it reboot and keep trying every 5 seconds or so? And let it go ahead and connect to wifi so remote debugging can continue?
what would be the syntax if I wanted to read the values, then convert them all to different units, then use Serial.print?
I am not using void print, this would all be in the void loop()
I am trying to use this sketch to read the BME280 sensor but I am running into a snag. For a long time I could not get anything to print on the Serial Monitor. I finally found a web page that said that the Bosch BME280 board has it address set to “0x76”. In checking the Adafruit_BME280.cpp file that the address it is looking for is “0x77”. But it can be changed by connecting the SDO pin to ground. That go it to print the “BME280 Test” but nothing else prints so I am thinking it is stopping at the “while(1);” So I don’t know why it is not reading the sensor data. Is the sensor defective or what? Any ideas? Let me know via email with any way to fix this. Thanks!
Hi.
To find out the address of your sensor, I recommend uploading this code to find out: https://raw.githubusercontent.com/RuiSantosdotme/Random-Nerd-Tutorials/master/Projects/LCD_I2C/I2C_Scanner.ino
Then, change the code accordingly.
Regards,
Sara
Thanks Sara, I have it working fine now. I used the i2c/12C scanner and found the address to be “0x77” but the problems that I was having showed up. I had purchased some other ones on Amazon and when I scanned them they were not addressed at all.
I guess they scammed me although it wasn’t very expensive. They are now in the trash and because of the lack of address is what had me so confused .
Hello, I have a problem with this sensor, the address is 0x76 but I receive following error: Could not find a valid BME280 sensor, check wiring!.
How can I resolve this problem?
Hi Giambattista,
I am having the same problem too. I even changed the sensor but nothing happened. Have you solved the problem?
Thank you.
Massimo
Hi.
Run an I2C scanner sketch to make sure of the I2C address of your sensor: https://randomnerdtutorials.com/esp32-i2c-communication-arduino-ide/#2
Regards,
Sara
I also recommend taking a look at this article: https://randomnerdtutorials.com/solved-could-not-find-a-valid-bme280-sensor/
Regards,
Sara
Hello Rui and Sara,
many thanks for all your informative tutorials.
Something of concern regarding voltage levels. The Arduino is a 5v device and the BME280 according to the bosch data sheet is 3.3V.
Why your wiring does not include some form of level shifting? is there not danger of damaging the sensor?
Best regards
Andre
Hi.
This sensor module works either with 5V or 3.3V. It comes with a 3.3V regulator and level shifting so you can use it with a 3.3V or 5V microcontroller.
Regards,
Sara
Does anyone have or know where I can get the KiCAD symbol and footprint for the BME280 in 4 and 6-pin versions?
I created the symbol and footprint myself. KiCAD is actually very easy to work with. I found a site that had the dimensions of the BME280 6-pin module, but it didn’t sound right. So.. I measured the module and found the dimensions listed on the site (not this site) were wrong. Moral of the story is — I could have measured it and created the symbol and footprint way faster than the time I wasted wondering where I could find an already-created symbol.
Does anybody know how to include the figures after the decimal?
Cheers
Paul
Hi Sara,
I hope you’re doing well. I want to use multiple BME280 sensors with an M5Stack Basic for a project I’m working on. Do you have any suggestions or recommendations on how to best implement this setup? Specifically, I’m interested to programmatically enable I2C pull-up resistors on the board. Will it work? Additionally, if you have any tips on ensuring reliable data readings, that would be incredibly helpful (I am planning on recording data for every 10 seconds using Ambient cloud service).
Hi.
We have a tutorial about I2C that explains how to use multiple sensors.
This might be useful: https://randomnerdtutorials.com/esp32-i2c-communication-arduino-ide/
If you don’t have pins available, you can use an I2C multiplexer: https://randomnerdtutorials.com/tca9548a-i2c-multiplexer-esp32-esp8266-arduino/
I hope this helps.
Regards,
Sara