ESP32 Web Server with BME280 – Advanced Weather Station

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.

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 one of the following tutorials to install the ESP32 on the Arduino IDE, if you haven’t already.

You might also like reading other BME280 guides:

Watch the Video Tutorial

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

Parts Required

To follow 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!

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.

BME280 Sensor Module Read temperature, humidity, and pressure

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:

  • SCK – this is the SPI Clock pin
  • SDO – MISO
  • SDI – MOSI
  • CS – Chip Select

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

  • SCK – this is also the SCL pin
  • SDI – this is also the SDA pin

Schematic

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.

BME280 Schematic Wiring temperature, humidity, and pressure

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

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.

Reading Temperature, Humidity, and Pressure BME280 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

Libraries

The code starts by including the needed libraries

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

SPI communication

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

/*#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 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.

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 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 by default. As you can see, you just need to create an Adafruit_BME280 object called bme.

Adafruit_BME280 bme; // I2C

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.

//Adafruit_BME280 bme(BME_CS); // hardware SPI
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI

setup()

In the setup() you start a serial communication

Serial.begin(9600);

And the sensor is initialized:

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

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:

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

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.

Demonstration Temperature, Humidity, and Pressure BME280 with Arduino IDE

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:

<table>
  <tr>
    <th>MEASUREMENT</th>
    <th>VALUE</th>
  </tr>
  <tr>
    <td>Temp. Celsius</td>
    <td>--- *C</td>
  </tr>
  <tr>
    <td>Temp. Fahrenheit</td>
    <td>--- *F</td>
  </tr>
  <tr>
    <td>Pressure</td>
    <td>--- hPa</td>
  </tr>
  <tr>
    <td>Approx. Altitude</td>
    <td>--- meters</td></tr>
  <tr>
    <td>Humidity</td>
    <td>--- %</td>
  </tr>
</table>

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.

Demonstration HTML Temperature, Humidity, and Pressure BME280 with Arduino IDE

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.

/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com  
*********/

// Load Wi-Fi library
#include <WiFi.h>
#include <Wire.h>
#include <Adafruit_BME280.h>
#include <Adafruit_Sensor.h>

//uncomment the following lines if you're using SPI
/*#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

// Replace with your network credentials
const char* ssid     = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

// Set web server port number to 80
WiFiServer server(80);

// Variable to store the HTTP request
String header;

// Current time
unsigned long currentTime = millis();
// Previous time
unsigned long previousTime = 0; 
// Define timeout time in milliseconds (example: 2000ms = 2s)
const long timeoutTime = 2000;

void setup() {
  Serial.begin(115200);
  bool status;

  // default settings
  // (you can also pass in a Wire library object like &Wire2)
  //status = bme.begin();  
  if (!bme.begin(0x76)) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }

  // Connect to Wi-Fi network with SSID and password
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  // Print local IP address and start web server
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  server.begin();
}

void loop(){
  WiFiClient client = server.available();   // Listen for incoming clients

  if (client) {                             // If a new client connects,
    currentTime = millis();
    previousTime = currentTime;
    Serial.println("New Client.");          // print a message out in the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected() && currentTime - previousTime <= timeoutTime) {  // loop while the client's connected
      currentTime = millis();
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        header += c;
        if (c == '\n') {                    // if the byte is a newline character
          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();
            
            // Display the HTML web page
            client.println("<!DOCTYPE html><html>");
            client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
            client.println("<link rel=\"icon\" href=\"data:,\">");
            // CSS to style the table 
            client.println("<style>body { text-align: center; font-family: \"Trebuchet MS\", Arial;}");
            client.println("table { border-collapse: collapse; width:35%; margin-left:auto; margin-right:auto; }");
            client.println("th { padding: 12px; background-color: #0043af; color: white; }");
            client.println("tr { border: 1px solid #ddd; padding: 12px; }");
            client.println("tr:hover { background-color: #bcbcbc; }");
            client.println("td { border: none; padding: 12px; }");
            client.println(".sensor { color:white; font-weight: bold; background-color: #bcbcbc; padding: 1px; }");
            
            // Web Page Heading
            client.println("</style></head><body><h1>ESP32 with BME280</h1>");
            client.println("<table><tr><th>MEASUREMENT</th><th>VALUE</th></tr>");
            client.println("<tr><td>Temp. Celsius</td><td><span class=\"sensor\">");
            client.println(bme.readTemperature());
            client.println(" *C</span></td></tr>");  
            client.println("<tr><td>Temp. Fahrenheit</td><td><span class=\"sensor\">");
            client.println(1.8 * bme.readTemperature() + 32);
            client.println(" *F</span></td></tr>");       
            client.println("<tr><td>Pressure</td><td><span class=\"sensor\">");
            client.println(bme.readPressure() / 100.0F);
            client.println(" hPa</span></td></tr>");
            client.println("<tr><td>Approx. Altitude</td><td><span class=\"sensor\">");
            client.println(bme.readAltitude(SEALEVELPRESSURE_HPA));
            client.println(" m</span></td></tr>"); 
            client.println("<tr><td>Humidity</td><td><span class=\"sensor\">");
            client.println(bme.readHumidity());
            client.println(" %</span></td></tr>"); 
            client.println("</body></html>");
            
            // The HTTP response ends with another blank line
            client.println();
            // Break out of the while loop
            break;
          } else { // if you got a newline, then clear currentLine
            currentLine = "";
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }
      }
    }
    // Clear the header variable
    header = "";
    // Close the connection
    client.stop();
    Serial.println("Client disconnected.");
    Serial.println("");
  }
}

View raw code

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

const char* ssid     = ""; 
const char* password = "";

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.

ESP32 IP Address Web Server Arduino IDE Serial Monitor

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.

ESP32 with BME280 Sensor Web Server with Arduino IDE

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.

// Load Wi-Fi library
#include <WiFi.h>
#include <Wire.h>
#include <Adafruit_BME280.h>
#include <Adafruit_Sensor.h>

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.

#define SEALEVELPRESSURE_HPA (1013.25)

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

Adafruit_BME280 bme; // I2C

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

const char* ssid     = "";
const char* password = "";

Then, you set your web server to port 80.

// Set web server port number to 80
WiFiServer server(80);

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

String header;

setup()

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

Serial.begin(115200);

You check that the BME280 sensor was successfully initialized.

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

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.

// Connect to Wi-Fi network with SSID and password
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
  delay(500);
  Serial.print(".");
}
// Print local IP address and start web server
Serial.println("");
Serial.println("WiFi connected.");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
server.begin();

loop()

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:

WiFiClient client = server.available(); // Listen for incoming clients

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.

if (client) { // If a new client connects,
  Serial.println("New Client."); // print a message out in the serial port
  String currentLine = ""; // make a String to hold incoming data from the client
  while (client.connected()) { // loop while the client's connected
    if (client.available()) { // if there's bytes to read from the client,
      char c = client.read(); // read a byte, then
      Serial.write(c); // print it out the serial monitor
      header += c;
      if (c == '\n') { // if the byte is a newline character
        // if the current line is blank, you got two newline characters in a row.
        // that's the end of the client HTTP request, so send a response:
        if (currentLine.length() == 0) {
          // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
          // and a content-type so the client knows what's coming, then a blank line:
          client.println("HTTP/1.1 200 OK");
          client.println("Content-type:text/html");
          client.println("Connection: close");
          client.println();

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.

client.println("<!DOCTYPE html><html>");
client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
client.println("<link rel=\"icon\" href=\"data:,\">");
// CSS to style the on/off buttons 
// Feel free to change the background-color and font-size attributes to fit your preferences
client.println("<style>body { text-align: center; font-family: \"Trebuchet MS\", Arial;}");
client.println("table { border-collapse: collapse; width:35%; margin-left:auto; margin-right:auto; }");
client.println("th { padding: 12px; background-color: #0043af; color: white; }");
client.println("tr { border: 1px solid #ddd; padding: 12px; }");
client.println("tr:hover { background-color: #bcbcbc; }");
client.println("td { border: none; padding: 12px; }");
client.println(".sensor { color:white; font-weight: bold; background-color: #bcbcbc; padding: 1px; }");
 
// Web Page Heading
client.println("</style></head><body><h1>ESP32 with BME280</h1>");
client.println("<table><tr><th>MEASUREMENT</th><th>VALUE</th></tr>");
client.println("<tr><td>Temp. Celsius</td><td><span class=\"sensor\">");
client.println(bme.readTemperature());
client.println(" *C</span></td></tr>"); 
client.println("<tr><td>Temp. Fahrenheit</td><td><span class=\"sensor\">");
client.println(1.8 * bme.readTemperature() + 32);
client.println(" *F</span></td></tr>"); 
client.println("<tr><td>Pressure</td><td><span class=\"sensor\">");
client.println(bme.readPressure() / 100.0F);
client.println(" hPa</span></td></tr>");
client.println("<tr><td>Approx. Altitude</td><td><span class=\"sensor\">");
client.println(bme.readAltitude(SEALEVELPRESSURE_HPA));
client.println(" m</span></td></tr>"); 
client.println("<tr><td>Humidity</td><td><span class=\"sensor\">");
client.println(bme.readHumidity());
client.println(" %</span></td></tr>"); 
client.println("</body></html>");

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:

client.println("<tr><td>Temp. Celsius</td><td><span class=\"sensor\">");
client.println(bme.readTemperature());
client.println(" *C</span></td></tr>");

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.

/*client.println("<tr><td>Temp. Celsius</td><td><span class=\"sensor\">");
client.println(bme.readTemperature());
client.println(" *C</span></td></tr>");*/

Closing the Connection

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

// Clear the header variable
header = "";
// Close the connection
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.

ESP32 Web Server with BME280 Weather Station

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.



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!

95 thoughts on “ESP32 Web Server with BME280 – Advanced Weather Station”

  1. Interesting, but seems a bit overkill to use an esp32 for this as an esp 8266 can do the same. With the esp32”s capabilities one may want to send the data via Bluetooth to ones phone

    Reply
    • Yes, that’s true. But this is a project example that shows how to use the BME280 and how to display sensor readings on a web server.
      The idea is that the users adapt this project to fulfill their needs.

      Reply
        • Interestingly the price difference between the esp8266 and the esp32 – at least where I get them from – has narrowed so much the esp32 is becoming the obvious choice anyway

          Reply
      • Has anyone else having problems making the Nodemcu Esp 32-S v1.1 board talk to the GY BME/P 280 sensor? I’m trying to program it using Windows 10 Arduino app (latest version) with all the different add on for both boards plus downloaded to esp memory addresses 077 and 078 . Used several boards of both with same result of no response monitored at 9600 and 115200.
        Using Driver Cp210x for win 64bit ,I set it he driver baud rate to the monitor rate. Is it me or just junk from China?

        Reply
  2. Great Project, it works fine…Thanks !!!
    I only have one problem. My WIFI Router shutdown from 00:00 until 06:00
    After WIFI lost there is no reconnect so i must reset ESP32 Web Server with BME280
    How can i fix the Problem ?

    Reply
  3. Hi

    These tutorials about the ESP32 are good, but you missing one thing that makes the code look awful!

    ESP32.also support the same WebServer library to handle request and response

    Please try it and update the code on these projects

    Thanks

    Reply
  4. Hi,

    Very interesting project !!

    However, when I compile in the Arduino IDE I get a “function not declared” error for the Adafruit BME280. I have the latest library installed but have noted that there exists numerious versions of the library. In particular the Adafruit_BME280.h and Adafruit_BME280.cpp files are different. I noticed that the constructors for the BME function are different. Which library/version should I use ? Would be great to be able to compile the project and develop it further. Many thanks.

    Reply
  5. Hi Rui,
    I would like to combine, this server with the “Weather Station – Data Logging to Excel” one.
    This provides the actual measurments and a long term storage, for statistic purposes for exemple.
    How should you proceed?
    Be carefull, I’m not a specialist…
    Thanks.
    jlb

    Reply
    • Hi Jean.
      Our “Weather Station – Data Logging to Excel” tutorial is written in LUA programming language. So, it is not straightforward to combine the two projects.
      However, instead of datalogging your readings to excel, you can experiment datalogging to Google Sheets.
      We have a tutorial on how to datalog to google sheets with the ESP32:
      https://randomnerdtutorials.com/esp32-esp8266-publish-sensor-readings-to-google-sheets/
      I hope this helps.
      Regards,
      Sara 🙂

      Reply
      • Hi Sara,

        Thank you very much for your answer.
        Indeed, it’s a good solution. I’ll try it.

        I’ve already an IFFT account, I’ve asked for one of your first course… a few years ago.

        Best regards,
        Jean-Luc

        Reply
  6. Hello Sara,

    How to measure the CPU usage and number of data processed per second of ESP32. Is there any method to determine it.

    Reply
  7. Hi there …
    perhaps you can help me a little bit ?!
    I wanted to do your porjekt with my hardware, but when i want to comlile the software for my D2 Mini i get this error messege anytime:

    “WiFi.h:79:9: error: initializing argument 1 of ‘int WiFiClass::begin(char*, const char*)’ [-fpermissive]
    int begin(char* ssid, const char *passphrase);
    ^
    exit status 1
    invalid conversion from ‘const char*’ to ‘char*’ [-fpermissive]”

    What can I do to solve it ? Thanks for a littel help.
    CU Kai

    Reply
      • Hi ..
        Sorry, after i removed the wifi.h libary the system can not finde it anymore.
        I will not be compiled. I treid also the WiFiEsp Libaries, but they will not work also.
        I want the create a ESP8266 with BME280 to build it into my Homebridge/Homekit.
        But i dit not find the right howto till now ;(
        Thanks a lot
        Kai

        Reply
      • Hi kevin.
        I’m sorry. We receive lots of emails and questions every day. It is very difficult for us to keep track of all questions.
        Answering your question: in this specific example, the ESP32 connects to your home network. But you can modify the code so that the ESP32 acts as an access point. That way, it doesn’t need to connect to your home network, and you can check the sensor readings by connecting to the ESP32 access point. Here is a tutorial on how to set your web servers with the ESP32 as an access point: https://randomnerdtutorials.com/esp32-access-point-ap-web-server/
        I hope this helps and thank you for your interest in our tutorials.
        Regards,
        Sara

        Reply
  8. I am not getting the Humidity value.All other i will get value. I am using same library which you mention here. Can you help me how to fix ?

    Reply
  9. Hi,

    I want to know if I upload the example BME280 test code successfully,

    and adjust the baud to 9600.

    Why cant I see anything on Serial Monitor.

    Thank you

    Reply
    • Hi KAI.
      After uploading the code and opening the Serial Monitor, press the ESP32 on-board RST button.
      Then, you should get all the information.
      Or are you getting any errors?
      Regards,
      Sara

      Reply
  10. Hi Sara,

    New problem appeared. It said that cant find a valid BME280.

    I link the SCL to GPIO22 and SDA to GPIO21, and also link the GND VIN to GND and VIN pins of ESP32.

    Maybe I need to buy another BME280?

    Regards,

    Kai

    Reply
  11. Hi! Very usefull project! Thank you!
    True, I wanted to ask me to help with the module CJMCU 8128 which contains sensors CCS811 HDC10XX BMP280 Can I use it in this project? Unfortunately, I’m just a beginner and it’s very difficult for me to figure it out. Thanks in advance!

    Reply
    • Hi.
      If it contains the BME280 sensor, I think it should work. But I haven’t one of those sensors to experiment.
      Regards,
      Sara

      Reply
  12. Hi folks!!
    I did it successfully….but sometime changes may help if given code not works..
    for example;;;
    (1)
    if (!bme.begin(0x76)) {
    Serial.println(“Could not find a valid BME280 sensor, check wiring!”);
    while (1);
    }
    Here, I2C use bme.begin() only…
    (2)
    this code does not work…
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(“.”);
    }

    Ans: use following:———

    WiFi.softAP(ssid, password);
    IPAddress IP = WiFi.softAPIP();
    Serial.print(“AP IP address: “);
    Serial.println(IP);

    Enjoy for rest of your coding……!!!

    Reply
  13. Great tutorial! However, I could get none of the examples for WiFi.h (core) to work…all cause watchdog resets. Changed library and code for ESP8266WiFi.h and works like a charm.

    Reply
  14. Hello, I am using this sketch on an Arduino Nano 33 IoT, and it seems to work fine up to the point where the code is:

    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(“.”);

    At this point it continually prints …… and goes no further. COuld someone help me why it does not connect to the Wifi? I have tried two different Wifi connections and it connects to neither.

    KR
    MGC

    Reply
    • Hi Miles.
      That usually means that you didn’t insert your network credentials, there’s a typo on the network credentials, or your board is very far away from your router and it’s not able to pick up wi-fi signal.
      Regards,
      Sara

      Reply
  15. hi. why this error:

    invalid conversion from ‘const char‘ to ‘char‘ [-fpermissive]

    This is abought wi fi i think.
    Thanks

    Reply
  16. No.
    The code is copy past and then the error
    Only insert wifi credentials like usual and inserted the requested libraries

    Reply
  17. HI.
    On sketch i get the error :
    invalid conversion from ‘const char‘ to ‘char‘ [-fpermissive]

    That refers to:

    WiFi.begin(ssid, password);

    Reply
    • Hi.
      In don’t know why you’re getting that error.
      But, change this
      const char* ssid = “REPLACE_WITH_YOUR_SSID”;
      to this:
      char* ssid = “REPLACE_WITH_YOUR_SSID”;
      Regards,
      Sara

      Reply
  18. OK. its done, changed sketch

    const char* ssid = “MEO-abcde”;
    const char* password = “123456”;

    to

    char* ssid = “MEO-abcde”;
    char* password = “123456”;

    Now it uploads but new problem that i have been working around with no results and i get this:

    Soft WDT reset
    ctx: cont
    sp: 3fff00f0 end: 3fff02e0 offset: 01b0

    stack>>>
    3fff02a0: feefeffe 3ffef284 3ffef284 40202578
    3fff02b0: feefeffe feefeffe feefeffe feefeffe
    3fff02c0: 3fffdad0 00000000 3ffef2a8 402055f0
    3fff02d0: feefeffe feefeffe 3ffef2c0 40100108
    <<<stack<<<
    ets Jan 8 2013,rst cause:2, boot mode:(3,6)
    load 0x4010f000, len 1384, room 16
    tail 8
    chksum 0x2d
    csum 0x2d
    v4ceabea9
    ~ld
    Could not find a valid BME280 sensor, check wiring!

    I did check and chek the wiring is like you descrive and no readings, any help please?
    Thanks

    Reply
  19. Need help, when running the bme280test program I get this:

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

    But when I run I2C scanner program it finds an I2C device at 0x76:

    Scanning…
    I2C device found at address 0x76 !
    done

    I don’t know what to try next? anyone have an idea? I tried different BME280-same thing.
    Thanks guys.
    Stephen

    Reply
    • Try the BMP280_sensortest example. I purchased (as advertised & labelled) a “BME/BMP280” sensor and the test program confirms that it is a BMP chip. Quick visual check is the BME has a square case and BMP is rectangular. Unfortunately most amazon sellers show the generic picture of the rectangular BME version, and you end up with the rectangular BMP. These only work with the <Adafruit_BMP280.h> library.

      Reply
      • Correction: Unfortunately most amazon sellers show the generic picture of the rectangular BME version, and you end up with the square BMP.

        Reply
  20. Didn’t you do an article about using ESP8266 with this sensor but using a webpage with a file called ESP_Chart.php? I built that and worked wonderfully, but I lost the esp8266 sketch file, can you give me a reference to it? thanks.

    Reply
  21. Im trying to run this on the exact hardware that you show in the demo. When i try to send the bme280 test code to the esp32 i get the error:

    src\main.cpp: In function ‘void loop()’:
    src\main.cpp:66:17: error: ‘printValues’ was not declared in this scope
    printValues();

    How would I resolve this issue?

    Reply
    • Hi.
      Copy the printValues() function before the setup().

      Cut this:

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

      And paste it before the setup().
      Regards,
      Sara

      Reply
  22. Hi

    I have a problem.
    C ++ shows me an error when compiling
    error: ‘printValues’ was not declared in this scope.
    Copying the entire function before setup() does not work.

    How would I resolve this issue?

    Reply
  23. I remember seeing two of these being used with a wiring schmatic, but I cant recall which tutorial it was. sketch showed using two bme’s in the same sketch. Could you please direct me to that tutorial?
    Thanks
    Nino

    Reply
  24. Dear Rui/Sara, As I understand it, this ESP32 Web Server with BME280 – Advanced Weather Station can only be read when a mobile phone connects trough the local network. Is there a solution when I would try to connect from my mobile phone while being out of reach of the local network, for instance when I would try to read the temperature in my house in the Netherlands, from a location in e.g. Portugal?
    A related question: I thought that I’ve seen a book on your website that specifically relates to ESP32 web server based weather stations. But I cannot find that book anymore. Any idea what the title was? I believe it was somewhere around 20 Euro?
    Thanks very much in advance, Ronald

    Reply
  25. Hi Sara,

    Could it possible be that in the HTML the ( end table) is not yet included…. ?
    Also in the other sketch (BME80 on multiple I2C) interfaces this seems the case.
    Regards,
    Piter.

    Reply
  26. Hello!

    After learning from and adapting from your examples. I find myself in a strange situation. I uploaded the ESP BME sketch to my ESP32-WROOM-32 for testing a soldered board (after fully developing my application on a solder-less breadboard.)

    Now, I cannot load any other sketch because of the error:
    A fatal error occurred: MD5 of file does not match data in flash!

    I have tried to erase the flash with esptool.py and even reload the firmware with:

    python esptool.py –chip auto –port /dev/ttyUSB0 –baud 115200 –before default_reset –after hard_reset write_flash -z –flash_mode dio –flash_freq 40m –flash_size 4MB 0x8000 partition_table/partition-table.bin 0x10000 ota_data_initial.bin 0xf000 phy_init_data.bin 0x1000 bootloader/bootloader.bin 0x100000 esp-at.bin 0x20000 at_customize.bin 0x24000 customized_partitions/server_cert.bin 0x39000 customized_partitions/mqtt_key.bin 0x26000 customized_partitions/server_key.bin 0x28000 customized_partitions/server_ca.bin 0x2e000 customized_partitions/client_ca.bin 0x30000 customized_partitions/factory_param.bin 0x21000 customized_partitions/ble_data.bin 0x3B000 customized_partitions/mqtt_ca.bin 0x37000 customized_partitions/mqtt_cert.bin 0x2a000 customized_partitions/client_cert.bin 0x2c000 customized_partitions/client_key.bin

    But, still, I cannot load any new sketch, though I can reload the existing sketch! Did I accidently load the sketch into the ESP’s SPI instead of the VSPI? Is there a good tutorial on how to completely erase and reprogram the ESP to factory condition?

    Reply
  27. Thanks for your help. I had already found those links. It seems to point to a different way of programming the ESP without using the Arduino IDE. After installing both esp-idf and esp-idf-v4.0.4 directories and other stuff, I am still unable to upload the firmware. I am unable to create a dfu.bin file. Using the Arduino IDE and the WiFi101 updater, I attempted to load the FirmWareUpdater, but I get:

    Error compiling for board ESP32 Dev Module.

    So, I’m stuck.

    Reply
  28. Bonjour,
    Concernant le ESP32 CAM (version DM-ESP32 S) j’obtiens une erreur:
    “E (25829) wifi:AP has neither DSSS parameter nor HT Information, drop it”
    lors du lancement du programme Web serveur . Le sketche “scanner” fonctionne parfaitement, mais me renvoie cette erreur sur un seul serveur. Avez vous une idée concernant cette erreur ?
    Merci par avance de votre aide.

    Reply
  29. Hi Sara,
    I used below line instead of what is in the above sketch and able to show degree symbol on web page instead of star ( * ) sign. Hope that this will help others.

    client.println(” °C”);

    Reply
    • Sorry it is not possible to write here since it automatically converts to degree sign.
      it should be
      & deg ; C
      without spaces in between.

      Reply
  30. Hi,
    All I’m getting with this sketch is
    “Could not find a valid BME280 sensor, check wiring!”
    Can anybody tell me what I’m doing wrong?

    Cheers
    Paul

    Reply
  31. My network password includes % sign. The compiler throws an expected initializer error due to the % sign. Is there an escape code or some other method to include the password? (I am unable to change the network passcode.)

    Reply
  32. really love to read and test all your work, thank you, it is a great way to learn the esp32.

    I have one issue with this project, the altitude doesn’t display correct, i know the netherlands for the most part is under sealevel but -187Meters is a bit much. What can I do to change this.

    Reply
    • Hi.
      You have to adjust the sea level pressure at your location on the following variable:
      #define SEALEVELPRESSURE_HPA (1013.25)
      Regards,
      Sara

      Reply
  33. A note of caution, the bme280 sensor boards I bought have the SCL and SDA pins reversed to the one shown in this project

    Reply

Leave a Reply to Sara Santos Cancel reply

Download Our Free eBooks and Resources

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