ESP32 with BME280 Sensor using Arduino IDE (Pressure, Temperature, Humidity)

This guide shows how to use the BME280 sensor module with the ESP32 to read pressure, temperature, humidity and estimate altitude using Arduino IDE. The BME280 sensor uses I2C or SPI communication protocol to exchange data with a microcontroller.

ESP32 with BME280 Sensor using Arduino IDE Pressure, Temperature, and Humidity

We’ll show you how to wire the sensor to the ESP32, install the required libraries, and write a simple sketch that displays the sensor readings.

Recommended reading: ESP32 Web Server with BME280 – Weather Station

Before proceeding with this tutorial you should have the ESP32 add-on installed in your Arduino IDE. Follow the next tutorial to install the ESP32 on the Arduino IDE, if you haven’t already.

You might also like reading other BME280 guides:

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. We’re using the module illustrated in the figure below.

BME280 Sensor I2C Module reads pressure, temperature, and humidity

This sensor communicates using I2C communication protocol, so the wiring is very simple. You can use the default ESP32 I2C pins as shown in the following table:

BME280ESP32
Vin3.3V
GNDGND
SCLGPIO 22
SDAGPIO 21

There are other versions of this sensor that can use either SPI or I2C communication protocols, like the module shown in the next figure:

BME280 Sensor Module SPI or I2C communication protocols

If you’re using one of these sensors, to use I2C communication protocol, use the following pins:

BME280ESP32
SCK (SCL Pin) GPIO 22
SDI (SDA pin) GPIO 21

If you use SPI communication protocol, you need to use the following pins:

BME280ESP32
SCK (SPI Clock)GPIO 18
SDO (MISO)GPIO 19
SDI (MOSI)GPIO 23
CS (Chip Select) GPIO 5

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 – ESP32 with BME280 using I2C

We’re going to use I2C communication with the BME280 sensor module. For that, wire the sensor to the ESP32 SDA and SCL pins, as shown in the following schematic diagram.

ESP32 with BME280 Wiring Schematic Diagram I2C

Recommended reading: ESP32 Pinout Reference Guide

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 BME280 library in Arduino IDE

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.

Installing Adafruit Unified Sensor Driver library

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.

ESP32 with BME280 Barometric Pressure Sensor and programmed with Arduino IDE

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 at https://randomnerdtutorials.com  
*********/

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

/*#include <SPI.h>
#define BME_SCK 18
#define BME_MISO 19
#define BME_MOSI 23
#define BME_CS 5*/

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

View raw code

We’ve made a few modifications to the sketch to make it fully compatible with the ESP32.

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:

/*#include <SPI.h>
#define BME_SCK 18
#define BME_MISO 19
#define BME_MOSI 23
#define BME_CS 5*/

Note: if you’re using SPI communication, you use the ESP32 SPI pins. For SPI communication on the ESP32 you can use either the HSPI or VSPI pins, as shown in the following table.

SPIMOSIMISOCLKCS
HSPI GPIO 13 GPIO 12GPIO 14GPIO 15
VSPI GPIO 23GPIO 19GPIO 18GPIO 5

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 depending on whether you’re using hardware or software SPI (hardware SPI uses the ESP32 default HSPI pins; software SPI uses the pins defined on the code).

//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 initialize the sensor:

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

We initialize the sensor with the 0x76 address. In case you’re not getting sensor readings, check the I2C address of your sensor. With the BME280 sensor wired to your ESP32, run this I2C scanner sketch to check the address of your sensor. Then, change the address if needed.

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 ESP32, and open the Serial Monitor at a baud rate of 9600. Press the on-board RST button to run the code. You should see the readings displayed on the Serial Monitor.

Printing BME280 pressure, temperature and humidity readings with ESP32 in Arduino IDE Serial Monitor

ESP32 Web Server Weather Station with BME280 Sensor

The BME280 sensor measures temperature, humidity, and pressure. So, you can easily build a compact weather station and monitor the measurements using a web server built with your ESP32.

To do that, you can follow this tutorial: ESP32 Web Server with BME280 Weather Station

ESP32 Web Server with BME280 Sensor Weather Station

Wrapping Up

This article was a quick guide on how to get pressure, temperature and humidity readings from a BME280 sensor with the ESP32 using Arduino IDE.

Now, you can take this project further and display your sensor readings in an OLED display; create a datalogger; or create a web server to display the latest sensor readings. Here’s a list of projects that might help with these ideas:

If you want to learn more about the ESP32, make sure you enroll in our course: “Learn ESP32 with Arduino IDE“.

Thanks for reading.



Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »

Enjoyed this project? Stay updated by subscribing our newsletter!

20 thoughts on “ESP32 with BME280 Sensor using Arduino IDE (Pressure, Temperature, Humidity)”

  1. When trying to connect with my browser, I get this on the serial monitor.
    What could be the problem?

    WiFi connected.
    IP address:
    172.20.10.2
    New Client.
    GET / HTTP/1.1
    Accept: text/html, application/xhtml+xml, image/jxr, */*
    Accept-Language: en-US,en-GB;q=0.8,en-DE;q=0.5,en;q=0.3
    User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko
    Accept-Encoding: gzip, deflate
    Host: 172.20.10.2
    Connection: Keep-Alive

    Exception (28):
    epc1=0x40202b6c epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000

    >>>stack>>>

    ctx: cont
    sp: 3ffffd80 end: 3fffffc0 offset: 01a0
    3fffff20: 3ffe88bd 3ffe8a63 3fffff50 40203714
    3fffff30: 0000000a 3ffe8a63 3ffee768 40202c50
    3fffff40: 3ffe85d9 3ffe8a63 3ffee908 402012e7
    3fffff50: 402063a8 00000000 00001388 4020fa2f
    3fffff60: 00000000 3ffefcfc 3fff000c 0000005f
    3fffff70: ff2f5054 3ffee7b0 3ffee908 4020267f
    3fffff80: 0000000a 3ffee7b0 3ffee908 402010d1
    3fffff90: 00000000 00000000 00000001 3ffee970
    3fffffa0: 3fffdad0 00000000 3ffee940 40203fc8
    3fffffb0: feefeffe feefeffe 3ffe8510 40100529
    <<<stack<<<

    ets Jan 8 2013,rst cause:2, boot mode:(3,7)

    load 0x4010f000, len 1384, room 16
    tail 8
    chksum 0x2d
    csum 0x2d
    v8b899c12
    ~ld

    Reply
  2. Again, Great tutorial! With a little fiddling, able to have temp in Fahrenheit, Pressure in InHg, and altitude in ft. 🙂

    Reply
  3. Hi, trying to follow this. I understand the code to some degree. Reading different sites examples helps.
    Question on the BME280. I have it connected to an ESP32 30 pin board. I copied the code, saved it as BME280.py and BMEreadout.main
    I have the option of pressing the boot or EN button? I’ve tried both with only the EN returning some error? I never see the readout? Any thoughts?

    Reply
  4. Following this tutorial I have setup stockton.co.z/lcars/ws.php to show not only temperature, humidity and pressure in my South African location but also, with the benefit of Raspberry devices, wind speed and rain fall.
    Other than the bme280 readings either overflowing or going negative about once a week system looks reasonable reliable. Reboot fixes that until I find the cause.
    BTW My server is a Raspberry Pi V4.

    Reply
  5. Thank you for this tutorial – it helped me to get up to speed with ESP32 a lot.

    I just want to make you aware that the temperature measurement in the BME280 and BMP280 is mainly for internal use in the sensor to compensate for temperature effects on the pressure and humidity signal. I made the experience that it can be some deg. C off from the real value! So, you either need to calibrate it in yourself or – if temperature is important for the project, take a dedicated temperature sensor like MCP9808 which are made for temperature measurement.

    Reply
  6. Does anyone have CAD drawings for a ESP-32 connected to an SD card & the BME280? I would like to order a PCB with these so that I don’t have to hardwire the components.

    Reply
  7. Hi, thanks for the tutorial. Kindly help me with the following problem.
    My serial monitor is showing nothing though I checked the sensor address and the boud rate of the monitor as well. What could be the problem.

    Reply
  8. Hello.

    I was having unreliable results from using a very cheap BMP/e280 sensor.

    After a lot of trial and error, I found it worked better with a BMP280I2C driver and modified the code accordingly.

    I display the results on a TFT display and combined results obtained from Openweathermap website.

    Thank you so much in getting me started.

    I highly recommend the TFT_eSPI driver and GitHub site for loads of advice on my IL9341 TFT display.

    Kind regards
    Melvin Lee

    Reply

Leave a Comment

Download Our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.