In this tutorial you’re going to learn how to create a web server with the ESP32 to display readings from the BME280 sensor module. The BME280 sensor measures temperature, humidity, and pressure. So, you can easily build a mini and compact weather station and monitor the measurements using your ESP32 web server. That’s what we’re going to do in this project.

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

Watch the Video Tutorial

This tutorial is available in video format (watch below) and in written format (continue reading).

You can use the preceding links or go directly to to find all the parts for your projects at the best price!

Introducing the BME280 Sensor Module

The BME280 sensor module reads temperature, humidity, and pressure. Because pressure changes with altitude, you can also estimate altitude. There are several versions of this sensor module, but we’re using the one shown in the figure below.

The sensor can communicate using either SPI or I2C communication protocols (there are modules of this sensor that just communicate with I2C, these just come with four pins).

To use SPI communication protocol, you use the following pins:

To use I2C communication protocol, the sensor uses the following pins:

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.

(This schematic uses the ESP32 DEVKIT V1 module version with 36 GPIOs – if you’re using another model, please check the pinout for the board you’re using.)

Installing the BME280 library

To take readings from the BME280 sensor module we’ll 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 Temperature, Humidity, and Pressure

To get familiar with the BME280 sensor, we’re going to use an example sketch from the library to see how to read temperature, humidity, and pressure.

After installing the BME280 library, and the Adafruit_Sensor library, open the Arduino IDE and, go to File > Examples > Adafruit BME280 library > bme280 test.

The code starts by including the needed libraries

SPI communication

As we’re going to use I2C communication you can comment the following lines:

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


Sea level pressure

A variable called SEALEVELPRESSURE_HPA is created.

This 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.

This example uses I2C communication by default. As you can see, you just need to create an Adafruit_BME280 object called bme.

If you would like 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.


In the setup() you start a serial communication

And the sensor is initialized:

Printing values

In the loop(), the printValues() function reads the values from the BME280 and prints the results in the Serial Monitor.

Reading temperature, humidity, pressure, and estimate altitude is as simple as using:

Upload the code to your ESP32, and open the Serial Monitor at a baud rate of 9600. You should see the readings displayed on the Serial Monitor.

Creating a Table in HTML

As you’ve seen in the beginning of the post, we’re displaying the readings in a web page with a table served by the ESP32. So, we need to write HTML text to build a table.

To create a table in HTML you use the <table> and </table> tags.

To create a row you use the <tr> and </tr> tags. The table heading is defined using the <th> and </th> tags, and each table cell is defined using the <td>and </td> tags.

To create a table for our readings, you use the following html text:

We create the header of the table with a cell called MEASUREMENT, and another called VALUE. Then, we create six rows to display each of the readings using the <tr> and </tr> tags. Inside each row, we create two cells, using the <td> and </td> tags, one with the name of the measurement, and another to hold the measurement value. The three dashes “—” should then be replaced with the actual measurements from the BME sensor.

You can save this text as table.html, drag the file into your browser and see what you have. The previous HTML text creates the following table.

The table doesn’t have any styles applied. You can use CSS to style the table with your own preferences. You may found this link useful: CSS Styling Tables.

Creating the Web Server

Now that you know how to take readings from the sensor, and how to build a table to display the results, it’s time to build the web server. If you’ve followed other ESP32 tutorials, you should be familiar with the majority of the code. If not, take a look at the ESP32 Web Server Tutorial.

Copy the following code to your Arduino IDE. Don’t upload it yet. First, you need to include your SSID and password.

Modify the following lines to include your SSID and password between the double quotes.

Then, check that you have the right board and COM port selected, and upload the code to your ESP32. After uploading, open the Serial Monitor at a baud rate of 115200, and copy the ESP32 IP address.

Open your browser, paste the IP address, and you should see the latest sensor readings. To update the readings, you just need to refresh the web page.

How the Code Works

This sketch is very similar with the sketch used in the ESP32 Web Server Tutorial. First, you include the WiFi library and the needed libraries to read from the BME280 sensor.

The next line defines a variable to save the pressure at the sea level. For more accurate altitude estimation, replace the value with the current sea level pressure at your location.

In the following line you create an Adafruit_BME280 object called bme that by default establishes a communication with the sensor using I2C.

As mentioned previously, you need to insert your ssid and password in the following lines inside the double quotes.

Then, you set your web server to port 80.

The following line creates a variable to store the header of the HTTP request:


In the setup(), we start a serial communication at a baud rate of 115200 for debugging purposes.

You check that the BME280 sensor was successfully initialized.

The following lines begin the Wi-Fi connection with WiFi.begin(ssid, password), wait for a successful connection and print the ESP IP address in the Serial Monitor.


In the loop(), we program what happens when a new client establishes a connection with the web server. The ESP is always listening for incoming clients with this line:

When a request is received from a client, we’ll save the incoming data. The while loop that follows will be running as long as the client stays connected. We don’t recommend changing the following part of the code unless you know exactly what you are doing.

Displaying the HTML web page

The next thing you need to do is sending a response to the client with the HTML text to build the web page.

The web page is sent to the client using this expression client.println(). You should enter what you want to send to the client as an argument.

The following code snippet sends the web page to display the sensor readings in a table.

Note: you can click here to view the full HTML web page.

Displaying the Sensor Readings

To display the sensor readings on the table, we just need to send them between the corresponding <td> and </td> tags. For example, to display the temperature:

Note: the <span> tag is useful to style a particular part of a text. In this case, we’re using the <span> tag to include the sensor reading in a class called “sensor”. This is useful to style that particular part of text using CSS.

By default the table is displaying the temperature readings in both Celsius degrees and Fahrenheit. You can comment the following three lines, if you want to display the temperature only in Fahrenheit degrees.

Closing the Connection

Finally, when the response ends, we clear the header variable, and stop the connection with the client with client.stop().

Wrapping Up

In summary, in this project you’ve learned how to read temperature, humidity, pressure, and estimate altitude using the BME280 sensor module. You also learned how to build a web server that displays a table with sensor readings. You can easily modify this project to display data from any other sensor.

If you like this project you may also like the following tutorials:

This is an excerpt from our course: Learn ESP32 with Arduino IDE. If you like ESP32 and you want to learn more, we recommend enrolling in Learn ESP32 with Arduino IDE course.

Thanks for reading.

This content was originally published here.