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.
You might also like reading other BME280 guides:
- ESP32 with BME280 Sensor using Arduino IDE
- ESP8266 with BME280 using Arduino IDE
- ESP32/ESP8266 with BME280 using MicroPython
- Arduino Board with BME280
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:
- ESP32 DOIT DEVKIT V1 Board – read ESP32 Development Boards Review and Comparison
- BME280 sensor module
- Breadboard
- Jumper wires
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.
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.
(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.
/*********
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();
}
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.
SPI | MOSI | MISO | CLK | CS |
HSPI | GPIO 13 | GPIO 12 | GPIO 14 | GPIO 15 |
VSPI | GPIO 23 | GPIO 19 | GPIO 18 | GPIO 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.
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.
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("");
}
}
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.
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.
// 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.
If you like this project you may also like the following tutorials:
- Build an All-in-One ESP32 Weather Station Shield
- ESP32 Publish Sensor Readings to Google Sheets (ESP8266 Compatible)
- ESP32 Data Logging Temperature to MicroSD Card
- ESP32 with Multiple DS18B20 Temperature Sensors
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.
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
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.
Hi, Sara
How about ESP32 as a client? I found some example but always error to POST data to server that i build.
thanks
You need to ensure that you’ve setup a proper HTTP POST request. It’s usually a problem with the data size (content length) in the request that might cause that issue.
very true and my comment certainly was not meant as criticism. If it came across that way I apologize
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
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?
You should always check the I2C address of the sensor, because it can change from board to board…
Hi Wf line
I had to change the BME280 address.
“bme.begin(0x76);” didn’t work, but “bme.begin(0x77);” did
Hi, had similar problem with Node MCU board.
I rolled back the Adafruit BME library version to 1.1.0 and that solved my problem. Hope it works for you.
Your problem, you have a lot of problems, Chinese products are very good.
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 ?
You might want to fix the link for the BME280 module. This is a $4 sensor and your link shows $46
Hi Jim.
Thanks for noticing. It is fixed now.
Thanks for this great example project for the ESP32 and BME280 sensor!
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
Hi.
Thank you for sharing.
We definitely have to take a look at that library.
Regards,
Sara 🙂
Here is the link to the example library on the official repository https://github.com/espressif/arduino-esp32/blob/master/libraries/WebServer/examples/AdvancedWebServer/AdvancedWebServer.ino
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.
Hi George.
We’re using the library on the following link:
https://github.com/adafruit/Adafruit_BME280_Library
You just need to click the “download” button, and then, follow the installation procedure.
You also need to include the Adafruit Sensor library:https://github.com/adafruit/Adafruit_Sensor
I hope this helps,
Regards,
Sara 🙂
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
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 🙂
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
Hello Sara,
How to measure the CPU usage and number of data processed per second of ESP32. Is there any method to determine it.
In the Arduino IDE, I don’t of any good methods to get that data and details… You might consider using ESP-IDF.
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
Hi Kai.
It seems that your Arduino IDE is not using the right WiFi library for this example. Because this sketch works as it is.
I recommend taking a look at the ESP32 troubleshooting guide bullet 5:
https://randomnerdtutorials.com/esp32-troubleshooting-guide/
I hope this helps,
Regards,
Sara 🙂
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
Does this allow you to access the weather readings webpage directly or does it have to through a home network?
Hello! I never got an answer to my question!
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
How can I add an image?
Hello Juan, this tutorial might help “How to Display Images in ESP32 and ESP8266 Web Server“: https://randomnerdtutorials.com/display-images-esp32-esp8266-web-server/
How can I make the server page refresh itself every so often?
With this web server the sensor readings are updated automatically “ESP32 DHT11/DHT22 Web Server“: https://randomnerdtutorials.com/esp32-dht11-dht22-temperature-humidity-web-server-arduino-ide/
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 ?
Hi Rushi.
Are you getting any errors? What value do you get for humidiyt? 0?
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
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
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
Hi Kai.
Can you run this I2C scanner sketch and find the address of your BME280 sensor?
https://raw.githubusercontent.com/RuiSantosdotme/Random-Nerd-Tutorials/master/Projects/LCD_I2C/I2C_Scanner.ino
Yours may be different than ours. Then, change the address on the following line if it is different:
status = bme.begin(0x76);
I hope this helps.
Regards,
Sara
Wow I find the address is 0×76
And change the code. Then
BME280 works!
Thank you!
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!
Hi.
If it contains the BME280 sensor, I think it should work. But I haven’t one of those sensors to experiment.
Regards,
Sara
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……!!!
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.
Oops! forgot to mention I’m using an esp8266 nodemcu, not an esp32.
Redfaced…tried it with an esp32 and yep, it compiled and ran ok as written.
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
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
hi. why this error:
invalid conversion from ‘const char‘ to ‘char‘ [-fpermissive]
This is abought wi fi i think.
Thanks
Hi.
Did you change anything in our code?
HI.
when i upload the code i get this error.
Any idea why?
Thanks
No.
The code is copy past and then the error
Only insert wifi credentials like usual and inserted the requested libraries
HI.
On sketch i get the error :
invalid conversion from ‘const char‘ to ‘char‘ [-fpermissive]
That refers to:
WiFi.begin(ssid, password);
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
Hi Sara, i did that and Worked but after upload i get the Error i have mencioned after in last message
Sara
thanks
that is the solution, now it is working!
73
Dick
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
I did check and chek the wiring is like you descrive and no readings, any help please?
Thanks
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
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.
Correction: Unfortunately most amazon sellers show the generic picture of the rectangular BME version, and you end up with the square BMP.
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.
Hi.
I think this is the project you are looking for: https://randomnerdtutorials.com/visualize-esp32-esp8266-sensor-readings-from-anywhere/
Regards,
Sara
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?
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
That worked perfectly.
Thank you!
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?
Sorry.
Had cut not copy.
Now everything works fine.
Thanks.
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
I found it, had a senior moment, https://randomnerdtutorials.com/esp32-i2c-communication-arduino-ide/.
Thanks again
nino
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
Hi Ronald.
This web server is only available on your local network.
You need to port forward your router to access it from another location or use a service like ngrok.
We have an eBook dedicated to Web Servers: https://randomnerdtutorials.com/build-web-servers-esp32-esp8266-ebook/
On this page, you can find all our eBooks: https://randomnerdtutorials.com/courses/
Regards,
Sara
Hi Sara, all clear.
Thanks for your quick reply.
Best regards,
Ronald
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.
Hi Piter.
What do you mean?
Can you try to explain your issue?
Regards,
Sara
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?
Hi.
I’m not sure. I never faced that issue.
In the links below you can find some suggestions:
– https://github.com/espressif/arduino-esp32/issues/1890
– https://www.esp32.com/viewtopic.php?t=4061
I hope this helps.
Regards,
Sara
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.
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.
Is that sensor directly provide “Absolute Humidity” or “Relative Humidity” ?
Hi.
It provides relative humidity.
Regards,
Sara
Thanks….
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”);
Sorry it is not possible to write here since it automatically converts to degree sign.
it should be
& deg ; C
without spaces in between.
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
Hi.
Check this article: https://randomnerdtutorials.com/solved-could-not-find-a-valid-bme280-sensor/
Regards,
Sara
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.)
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.
Hi.
You have to adjust the sea level pressure at your location on the following variable:
#define SEALEVELPRESSURE_HPA (1013.25)
Regards,
Sara
Is the BME280 5V or 3.3V
The module can run with 3.3V or 5V.
A note of caution, the bme280 sensor boards I bought have the SCL and SDA pins reversed to the one shown in this project