This tutorial shows how to build a web server weather station with the ESP32 to display sensor readings from the BME680 environmental sensor: gas (air quality), temperature, humidity and pressure. The readings are updated automatically on the web server using Server-Sent Events (SSE). The ESP32 will be programmed using Arduino IDE.
To build the web server we’ll use the ESP Async Web Server library that provides an easy way to build an asynchronous web server.
BME680 Environmental Sensor
The BME680 is an environmental sensor that combines gas, temperature, humidity and pressure sensors. The gas sensor can detect a broad range of gases like volatile organic compounds (VOC). For this reason, the BME680 can be used in indoor air quality control.
The BME680 contains a MOX (Metal-oxide) sensor that detects VOCs in the air. This sensor gives you a qualitative idea of the sum of VOCs/contaminants in the surrounding air. As a raw signal, the BME680 outputs resistance values. These values change due to variations in VOC concentrations:
- Higher concentration of VOCs » Lower resistance
- Lower concentration of VOCs » Higher resistance
For more information about the BME680, read our getting started guide: ESP32: BME680 Environmental Sensor using Arduino IDE (Gas, Pressure, Humidity, Temperature).
Parts Required
To complete this tutorial you need the following parts:
You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!
Schematic – ESP32 with BME680
The BME680 can communicate using I2C or SPI communication protocols. In this tutorial, we’ll use I2C communication protocol.
Follow the next schematic diagram to wire the BME680 to the ESP32 using the default I2C pins.
Recommended reading: ESP32 Pinout Reference – Which GPIO pins should you use?
Preparing Arduino IDE
We’ll program the ESP32 board using Arduino IDE. So, make sure you have the ESP32 add-on installed. Follow the next tutorial:
You also need to install the following libraries.
Follow the next instructions to install them.
Installing the BME680 Library
To get readings from the BME680 sensor module we’ll use the Adafruit_BME680 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 bme680 ” on the Search box and install the library.
Installing the Adafruit_Sensor Library
To use the BME680 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 the ESPAsyncWebServer library
The ESPAsyncWebServer library is not available to install in the Arduino IDE Library Manager. So, you need to install it manually.
Follow the next steps to install the ESPAsyncWebServer library:
- Click here to download the ESPAsyncWebServer library. You should have a .zip folder in your Downloads folder
- Unzip the .zip folder and you should get ESPAsyncWebServer-master folder
- Rename your folder from
ESPAsyncWebServer-masterto ESPAsyncWebServer - Move the ESPAsyncWebServer folder to your Arduino IDE installation libraries folder
Alternatively, in your Arduino IDE, you can go to Sketch > Include Library > Add .zip Library and select the library you’ve just downloaded.
Installing the ESPAsync TCP Library
The ESPAsyncWebServer library requires the ESPAsyncTCP library to work. Follow the next steps to install that library:
- Click here to download the ESPAsyncTCP library. You should have a .zip folder in your Downloads folder
- Unzip the .zip folder and you should get ESPAsyncTCP-master folder
- Rename your folder from
ESPAsyncTCP-masterto ESPAsyncTCP - Move the ESPAsyncTCP folder to your Arduino IDE installation libraries folder
- Finally, re-open your Arduino IDE
Alternatively, in your Arduino IDE, you can go to Sketch > Include Library > Add .zip Library and select the library you’ve just downloaded.
ESP32 BME680 Web Server Code
Open your Arduino IDE and copy the following code. To make it work, you need to insert your network credentials: SSID and password.
/*********
Rui Santos
Complete project details at https://RandomNerdTutorials.com/esp32-bme680-sensor-arduino/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
*********/
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BME680.h"
#include <WiFi.h>
#include "ESPAsyncWebServer.h"
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
//Uncomment if using SPI
/*#define BME_SCK 18
#define BME_MISO 19
#define BME_MOSI 23
#define BME_CS 5*/
Adafruit_BME680 bme; // I2C
//Adafruit_BME680 bme(BME_CS); // hardware SPI
//Adafruit_BME680 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK);
float temperature;
float humidity;
float pressure;
float gasResistance;
AsyncWebServer server(80);
AsyncEventSource events("/events");
unsigned long lastTime = 0;
unsigned long timerDelay = 30000; // send readings timer
void getBME680Readings(){
// Tell BME680 to begin measurement.
unsigned long endTime = bme.beginReading();
if (endTime == 0) {
Serial.println(F("Failed to begin reading :("));
return;
}
if (!bme.endReading()) {
Serial.println(F("Failed to complete reading :("));
return;
}
temperature = bme.temperature;
pressure = bme.pressure / 100.0;
humidity = bme.humidity;
gasResistance = bme.gas_resistance / 1000.0;
}
String processor(const String& var){
getBME680Readings();
//Serial.println(var);
if(var == "TEMPERATURE"){
return String(temperature);
}
else if(var == "HUMIDITY"){
return String(humidity);
}
else if(var == "PRESSURE"){
return String(pressure);
}
else if(var == "GAS"){
return String(gasResistance);
}
}
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
<title>BME680 Web Server</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
<link rel="icon" href="data:,">
<style>
html {font-family: Arial; display: inline-block; text-align: center;}
p { font-size: 1.2rem;}
body { margin: 0;}
.topnav { overflow: hidden; background-color: #4B1D3F; color: white; font-size: 1.7rem; }
.content { padding: 20px; }
.card { background-color: white; box-shadow: 2px 2px 12px 1px rgba(140,140,140,.5); }
.cards { max-width: 700px; margin: 0 auto; display: grid; grid-gap: 2rem; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.reading { font-size: 2.8rem; }
.card.temperature { color: #0e7c7b; }
.card.humidity { color: #17bebb; }
.card.pressure { color: #3fca6b; }
.card.gas { color: #d62246; }
</style>
</head>
<body>
<div class="topnav">
<h3>BME680 WEB SERVER</h3>
</div>
<div class="content">
<div class="cards">
<div class="card temperature">
<h4><i class="fas fa-thermometer-half"></i> TEMPERATURE</h4><p><span class="reading"><span id="temp">%TEMPERATURE%</span> °C</span></p>
</div>
<div class="card humidity">
<h4><i class="fas fa-tint"></i> HUMIDITY</h4><p><span class="reading"><span id="hum">%HUMIDITY%</span> %</span></p>
</div>
<div class="card pressure">
<h4><i class="fas fa-angle-double-down"></i> PRESSURE</h4><p><span class="reading"><span id="pres">%PRESSURE%</span> hPa</span></p>
</div>
<div class="card gas">
<h4><i class="fas fa-wind"></i> GAS</h4><p><span class="reading"><span id="gas">%GAS%</span> KΩ</span></p>
</div>
</div>
</div>
<script>
if (!!window.EventSource) {
var source = new EventSource('/events');
source.addEventListener('open', function(e) {
console.log("Events Connected");
}, false);
source.addEventListener('error', function(e) {
if (e.target.readyState != EventSource.OPEN) {
console.log("Events Disconnected");
}
}, false);
source.addEventListener('message', function(e) {
console.log("message", e.data);
}, false);
source.addEventListener('temperature', function(e) {
console.log("temperature", e.data);
document.getElementById("temp").innerHTML = e.data;
}, false);
source.addEventListener('humidity', function(e) {
console.log("humidity", e.data);
document.getElementById("hum").innerHTML = e.data;
}, false);
source.addEventListener('pressure', function(e) {
console.log("pressure", e.data);
document.getElementById("pres").innerHTML = e.data;
}, false);
source.addEventListener('gas', function(e) {
console.log("gas", e.data);
document.getElementById("gas").innerHTML = e.data;
}, false);
}
</script>
</body>
</html>)rawliteral";
void setup() {
Serial.begin(115200);
// Set the device as a Station and Soft Access Point simultaneously
WiFi.mode(WIFI_AP_STA);
// Set device as a Wi-Fi Station
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Setting as a Wi-Fi Station..");
}
Serial.print("Station IP Address: ");
Serial.println(WiFi.localIP());
Serial.println();
// Init BME680 sensor
if (!bme.begin()) {
Serial.println(F("Could not find a valid BME680 sensor, check wiring!"));
while (1);
}
// Set up oversampling and filter initialization
bme.setTemperatureOversampling(BME680_OS_8X);
bme.setHumidityOversampling(BME680_OS_2X);
bme.setPressureOversampling(BME680_OS_4X);
bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
bme.setGasHeater(320, 150); // 320*C for 150 ms
// Handle Web Server
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html, processor);
});
// Handle Web Server Events
events.onConnect([](AsyncEventSourceClient *client){
if(client->lastId()){
Serial.printf("Client reconnected! Last message ID that it got is: %u\n", client->lastId());
}
// send event with message "hello!", id current millis
// and set reconnect delay to 1 second
client->send("hello!", NULL, millis(), 10000);
});
server.addHandler(&events);
server.begin();
}
void loop() {
if ((millis() - lastTime) > timerDelay) {
getBME680Readings();
Serial.printf("Temperature = %.2f ºC \n", temperature);
Serial.printf("Humidity = %.2f % \n", humidity);
Serial.printf("Pressure = %.2f hPa \n", pressure);
Serial.printf("Gas Resistance = %.2f KOhm \n", gasResistance);
Serial.println();
// Send Events to the Web Server with the Sensor Readings
events.send("ping",NULL,millis());
events.send(String(temperature).c_str(),"temperature",millis());
events.send(String(humidity).c_str(),"humidity",millis());
events.send(String(pressure).c_str(),"pressure",millis());
events.send(String(gasResistance).c_str(),"gas",millis());
lastTime = millis();
}
}
Insert your network credentials in the following variables and the code will work straight away.
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
How the Code Works
Read this section to learn how the code works, or skip to the next section.
Including Libraries
Start by including the necessary libraries. The Wire library is needed for I2C communication protocol. We also include the SPI library if you want to use SPI communication instead.
#include <Wire.h>
#include <SPI.h>
The Adafruit_Sensor and Adafruit_BME680 libraries are needed to interface with the BME680 sensor.
#include <Adafruit_Sensor.h>
#include "Adafruit_BME680.h"
The WiFi and ESPAsyncWebServer libraries are used to create the web server.
#include <WiFi.h>
#include "ESPAsyncWebServer.h"
Network Credentials
Insert your network credentials in the following variables, so that the ESP32 can connect to your local network using Wi-Fi.
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
I2C Communication
Create an Adafruit_BME680 object called bme on the default ESP32 I2C pins.
Adafruit_BME680 bme; // I2C
If you want to use SPI communication instead, you need to define the ESP32 SPI pins on the following lines (to uncomment remove the /* and */):
/*#define BME_SCK 18
#define BME_MISO 19
#define BME_MOSI 23
#define BME_CS 15*/
And then, create an Adafruit_BME680 object using those pins (to uncomment remove the //).
//Adafruit_BME680 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK);
Declaring Variables
The temperature, humidity, pressure and gasResistance float variables will be used to hold BME680 sensor readings.
float temperature;
float humidity;
float pressure;
float gasResistance;
The lastTime and the timerDelay variables will be used to update sensor readings every X number of seconds. As an example, we’ll get new sensor readings every 30 seconds (30000 milliseconds). You can change that delay time in the timerDelay variable.
unsigned long lastTime = 0;
unsigned long timerDelay = 30000;
Create an Async Web Server on port 80.
AsyncWebServer server(80);
Create Event Source
To automatically display the information on the web server when a new reading arrives, we’ll use Server-Sent Events (SSE).
The following line creates a new event source on /events.
AsyncEventSource events("/events");
Server-Sent Events allow a web page (client) to get updates from a server. We’ll use this to automatically display new readings on the web server page when new BME680 readings are available.
Important: Server-sent events are not supported on Internet Explorer.
Get BME680 Readings
The getBME680Reading() function gets gas, temperature, humidity and pressure readings from the BME680 sensor and saves them on the gasResistance, temperature, humidity and pressure variables.
void getBME680Readings(){
// Tell BME680 to begin measurement.
unsigned long endTime = bme.beginReading();
if (endTime == 0) {
Serial.println(F("Failed to begin reading :("));
return;
}
if (!bme.endReading()) {
Serial.println(F("Failed to complete reading :("));
return;
}
temperature = bme.temperature;
pressure = bme.pressure / 100.0;
humidity = bme.humidity;
gasResistance = bme.gas_resistance / 1000.0;
}
Processor
The processor() function replaces any placeholders on the HTML text used to build the web page with the current sensor readings.
String processor(const String& var){
getBME680Readings();
//Serial.println(var);
if(var == "TEMPERATURE"){
return String(temperature);
}
else if(var == "HUMIDITY"){
return String(humidity);
}
else if(var == "PRESSURE"){
return String(pressure);
}
else if(var == "GAS"){
return String(gasResistance);
}
}
This allows us to display the current sensor readings on the web page when you access it for the first time. Otherwise, you would see a blank space until new readings were available (which can take some time depending on the delay time you’ve defined on the code).
Building the Web Page
The index_html variable contains all the HTML, CSS and JavaScript to build the web page. We won’t go into detail on how the HTML and CSS works. We’ll just take a look at how to handle the events sent by the server.
Let’s take a quick look at the line that displays the temperature:
<h4><i class="fas fa-thermometer-half"></i> TEMPERATURE</h4><p><span class="reading"><span id="temp">%TEMPERATURE%</span> °C</span></p>
You can see that the %TEMPERATURE% placeholder is surrounded by <span id=”temp”></span> tags. The HTML id attribute is used to specify a unique id for an HTML element.
It is used to point to a specific style or it can be used by JavaScript to access and manipulate the element with that specific id. That’s what we’re going to do.
For instance, when the web server receives a new event with the latest temperature reading, we’ll update the HTML element with the id “temp” with the new reading.
A similar process is done to update the other readings.
Handle Events
Create a new EventSource object and specify the URL of the page sending the updates. In our case, it’s /events.
if (!!window.EventSource) {
var source = new EventSource('/events');
Once you’ve instantiated an event source, you can start listening for messages from the server with addEventListener().
These are the default event listeners, as shown here in the AsyncWebServer documentation.
source.addEventListener('open', function(e) {
console.log("Events Connected");
}, false);
source.addEventListener('error', function(e) {
if (e.target.readyState != EventSource.OPEN) {
console.log("Events Disconnected");
}
}, false);
source.addEventListener('message', function(e) {
console.log("message", e.data);
}, false);
Then, add the event listener for “temperature”.
source.addEventListener('temperature', function(e) {
When a new temperature reading is available, the ESP32 sends an event (“temperature”) to the client. The following lines handle what happens when the browser receives that event.
console.log("temperature", e.data);
document.getElementById("temp").innerHTML = e.data;
Basically, print the new readings on the browser console, and put the received data into the element with the corresponding id (“temp“) on the web page.
A similar processor is done for humidity, pressure and gas resistance.
source.addEventListener('humidity', function(e) {
console.log("humidity", e.data);
document.getElementById("hum").innerHTML = e.data;
}, false);
source.addEventListener('pressure', function(e) {
console.log("pressure", e.data);
document.getElementById("pres").innerHTML = e.data;
}, false);
source.addEventListener('gas', function(e) {
console.log("gas", e.data);
document.getElementById("gas").innerHTML = e.data;
}, false);
setup()
In the setup(), initialize the Serial Monitor.
Serial.begin(115200);
Connect the ESP32 to your local network and print the ESP32 IP address.
// Set device as a Wi-Fi Station
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Setting as a Wi-Fi Station..");
}
Serial.print("Station IP Address: ");
Serial.println(WiFi.localIP());
Serial.println();
Initialize the BME680 sensor.
// Init BME680 sensor
if (!bme.begin()) {
Serial.println(F("Could not find a valid BME680 sensor, check wiring!"));
while (1);
}
// Set up oversampling and filter initialization
bme.setTemperatureOversampling(BME680_OS_8X);
bme.setHumidityOversampling(BME680_OS_2X);
bme.setPressureOversampling(BME680_OS_4X);
bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
bme.setGasHeater(320, 150); // 320*C for 150 ms
Handle Requests
When you access the ESP32 IP address on the root / URL, send the text that is stored on the index_html variable to build the web page and pass the processor as argument, so that all placeholders are replaced with the latest sensor readings.
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html, processor);
});
Server Event Source
Set up the event source on the server.
// Handle Web Server Events
events.onConnect([](AsyncEventSourceClient *client){
if(client->lastId()){
Serial.printf("Client reconnected! Last message ID that it got is: %u\n", client->lastId());
}
// send event with message "hello!", id current millis
// and set reconnect delay to 1 second
client->send("hello!", NULL, millis(), 10000);
});
server.addHandler(&events);
Finally, start the server.
server.begin();
loop()
In the loop(), get new sensor readings:
getBME680Readings();
Print the new readings in the Serial Monitor.
Serial.printf("Temperature = %.2f ºC \n", temperature);
Serial.printf("Humidity = %.2f % \n", humidity);
Serial.printf("Pressure = %.2f hPa \n", pressure);
Serial.printf("Gas Resistance = %.2f KOhm \n", gasResistance);
Serial.println();
Finally, send events to the browser with the newest sensor readings to update the web page.
// Send Events to the Web Server with the Sensor Readings
events.send("ping",NULL,millis());
events.send(String(temperature).c_str(),"temperature",millis());
events.send(String(humidity).c_str(),"humidity",millis());
events.send(String(pressure).c_str(),"pressure",millis());
events.send(String(gasResistance).c_str(),"gas",millis());
The following diagram summarizes how Server-Sent Events work to update the web page.
Uploading the Code
Now, upload the code to your ESP32. Make sure you have the right board and COM port selected.
After uploading, open the Serial Monitor at a baud rate of 115200. Press the ESP32 on-board RST/EN button. The ESP32 IP address should be printed in the serial monitor.
Demonstration
Open a browser in your local network and type the ESP32 IP address. You should get access to the ESP32 web server with the latest BME680 readings.
The readings are updated automatically using Server-Sent Events.
Wrapping Up
In this tutorial you’ve learned how to build an asynchronous web server weather station with the ESP32 to display BME680 sensor readings – gas (air quality), temperature, humidity and pressure – and how to update the readings automatically on the web page using Server-Sent Events.
We have other web server tutorials that you may like:
- ESP32 DHT11/DHT22 Web Server – Temperature and Humidity using Arduino IDE
- ESP32 Async Web Server – Control Outputs with Arduino IDE
- ESP32 Web Server with BME280 – Advanced Weather Station
- ESP32 DS18B20 Temperature Sensor with Arduino IDE (Single, Multiple, Web Server)
We hope you’ve found this project interesting. Learn more about the ESP32 with our resources:
- Learn ESP32 with Arduino IDE (eBook + Video Course)
- MicroPython Programming with ESP32 and ESP8266
- More ESP32 Projects and Tutorials…
Thanks for reading.
In ESPAsysncWebServer.h there are the statements
#ifdef ESP32
#include <WiFi.h>
#include <AsyncTCP.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
i.e., for ESP 32 <AsyncTCP.h> is included instead of <ESPAsyncTCP.h>. When I install the latter as you say in the tutorial, <AsyncTCP.h> is not found and the project does not compile correctly. Should I include another library (where do I find the correct AsyncTCP library?) of should I edit ESPAsysncWebServer.h (replace #include <AsyncTCP.h> by <ESPAsyncTCP.h>)?
Hi.
If the library is not called, you don’t need to include it.
But to prevent issues, if you’re using an ESP32, you can delete the lines that refer to the ESP8266:
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
What code are you following?
Regards,
Sara
Forcing the web page to update by re-entering the IP address or on first reading, I get ‘Failed to complete reading :(‘ in the terminal. Is this normal? Can it be avoided?
Hi William.
In this project, the web page is updated automatically when new readings are available.
There’s no need to force an update because it won’t have new readings.
Regards,
Sara
I try to fix this tutorial. I use a ESP32 with 30-pin. Board: “ESP32 DEV Module”.
No changes in Boardmanager.
Sensor sketch-line: Adafruit_BME680 bme; // I2C
Compiling and Uploading works without errors.
But after reset/start I get the serial monitor message:
rst:0x3 (SW_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1216
ho 0 tail 12 room 4
load:0x40078000,len:9720
ho 0 tail 12 room 4
load:0x40080400,len:6352
entry 0x400806b8
Can you please help me fixing this problem?
Now it works. The board was malfunction. No WLan.
Thanks
Great tutorial, as always!
About BME680 I read that the Gas Resistance is only half way to determin Air Qualität as the Signal needs further processing. There is a Bosch BSEC library having all maths included, but I struggle to get this precompiled code library to work with the ESP32 🙁
Maybe you could do a Follow Up on this in near future 😉
The two decimal points of precision displayed on the web page probably represent more precision than the capability of the device. rather than displaying 80.45 is would be better to display 80.5 . Rounding to one decimal is easy but the trailing zero is still displayed. Can the rounding function be accomplished the a trailing zero is not displayed? Perhapse in the Java script?
Can you explain to me, how I can convert the gas-data from kOhm to PPM.
I know that the air is bad, when CO² is bigger then 1.000 PPM.
400 PPM is fresh air
1.000 PPM is bad air
2.000 PPM means death
what changes require if I use a different board as I have adafruit huzzah feather.
I try this code on my board and it gives this message.
Setting as a Wi-Fi Station..
continuously.
Hi.
You need to make sure you insert your network credentials in the ssid and password variables.
Regards,
Sra
Hello
I am using ESP32 board with BME 680 i have successfully made it work with Micro Python script from your project.
Was trying the Arduino IDE Webserver script for the same (ESP32 with BME680) and have the following error:
Arduino: 1.8.13 (Windows 10), Board: “ESP32 FM DevKit, 921600, None”
Multiple libraries were found for “WiFi.h”
Used: C:\Users\RanjitPrabhu\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries\WiFi
In file included from E:\Users\RanjitPrabhu\Documents\Arduino\sketch_dec21b\sketch_dec21b.ino:17:0:
Not used: C:\Program Files (x86)\Arduino\libraries\WiFi
E:\Users\RanjitPrabhu\Documents\Arduino\libraries\ESPAsyncWebServer\src/ESPAsyncWebServer.h:33:22: fatal error: AsyncTCP.h: No such file or directory
compilation terminated.
exit status 1
Error compiling for board ESP32 FM DevKit.
This report would have more information with
“Show verbose output during compilation”
option enabled in File -> Preferences.
Hi.
This error: “fatal error: AsyncTCP.h: No such file” means that you need to install the AsyncTCP library.
Regards,
Sara
Hello, i am getting the same error but I have the library downloaded and within my Arduino Libraries? Any other insight on what to do to make it work?
That error means that it can’t find the library.
You may have several Arduino IDE installations and you may be putting the library in the wrong folder.
Regards,
Sara
Hi
I had problems compiling the code and after some searching found out that at least in my case solution was to include following libraries:
ESPAsyncWebServer
AsyncTCP-master (https://github.com/me-no-dev/AsyncTCP)
not to install ESPAsyncTCP-master
Hope this helps someone struggling with the same problems.
Good day Mika,
Thank you for your post, as it solved my problem as well.
Thanks again!
Cheers
Sam
Hey, just wanted to let you know that your code seems to have been plagiarized here, without the copyright comment included:XXXXX
Hi Caleb.
Thanks for letting us know.
In fact, that website plagiarizes almost all our content, not just the code, but complete tutorials.
It’s very annoying, but unfortunately, there’s nothing we can do.
I can hope that people understand that ours is the original content.
Thanks once again.
Regards,
Sara
Good afternoon.
After sewing ESP32 data:
15:42:45.579 -> Setting as a Wi-Fi Station..
15:42:45.579 -> Station IP Address: 192.168.1.100
But the site page does not open…!!
In the process it gives an error:
C:\Users.…\Documents\Arduino\Monin\Monin.ino: In function ‘String processor(const String&)’:
C:\Users.…\Documents\Arduino\Monin\Monin.ino:76:1: warning: control reaches end of non-void function [-Wreturn-type]
What to do?
Hi.
Modify the processor() function as follows:
String processor(const String& var){
getBME680Readings();
//Serial.println(var);
if(var == “TEMPERATURE”){
return String(temperature);
}
else if(var == “HUMIDITY”){
return String(humidity);
}
else if(var == “PRESSURE”){
return String(pressure);
}
else if(var == “GAS”){
return String(gasResistance);
}
return String();
}
Let me know if this solves the issue.
Regards.
Sara
Hi Sara,
me not knowing to code, I got this conversion to air quality instead of gas resistance, can you provide an alternate code?
comp_gas = log(R_gas[ohm]) + 0.04 log(Ohm)/%rh * hum[%rh]
platform: template
name: “BME680 IAQ”
id: IAQ
unit_of_measurement: IAQ
lambda: ‘return log(id(g_res).state) + 0.04 * id(hum).state;’
https://community.home-assistant.io/t/bme680-gas-resistance-values/140719/13
Thanks for putting this up. I used a freenove wrover board I got as part of a kit off of amazon. My sensor is a BME680 from Pimoroni LTD. I eventually realized that the default address for this is different from the Adafruit version so I cut the trace to change the address.
I tried to install the libraries via your instructions but I got a message about multiple wifi.h’s found. Went into library manager and downloaded ESPAsyncWebSrv and made the change to the header file.
It is working, I have an Adafruit sensor on order along with other items to help her make a living.
How do you change the sensor address in the program. I’m pretty new at this.
I sent you some coffee money via paypal. Thanks!
Hi.
You can run the following code to find the Sensor I2C address: https://raw.githubusercontent.com/RuiSantosdotme/Random-Nerd-Tutorials/master/Projects/LCD_I2C/I2C_Scanner.ino
After getting your sensor address, you just need to pass it as an argument to the begin() method. For example, if your address is 0x27, use the following line like this:
if (!bme.begin(0x27)) {
I hope this helps.
Regards,
Sara
When compiling the program, the following two errors occur:
C:\Users\rogga\Documents\Arduino\sketch_jun17a_ESP32_BME680_Web-Server\sketch_jun17a_ESP32_BME680_Web-Server.ino: In function ‘void loop()’:
C:\Users\rogga\Documents\Arduino\sketch_jun17a_ESP32_BME680_Web-Server\sketch_jun17a_ESP32_BME680_Web-Server.ino:212:19: error: unknown conversion type character ‘\x0a’ in format [-Werror=format=]
Serial.printf(“Humidity = %.2f % \n”, humidity);
^~~~~~~~~~~~~~~~~~~~~~
C:\Users\rogga\Documents\Arduino\sketch_jun17a_ESP32_BME680_Web-Server\sketch_jun17a_ESP32_BME680_Web-Server.ino: In function ‘String processor(const String&)’:
C:\Users\rogga\Documents\Arduino\sketch_jun17a_ESP32_BME680_Web-Server\sketch_jun17a_ESP32_BME680_Web-Server.ino:77:1: error: control reaches end of non-void function [-Werror=return-type]
}
Hi.
Make sure you copy the whole code.
It seems you’re missing a } at the end of the code.
Regards,
Sara
Hi,
There is error with % in printf format. To printf %, you need to put %% in printf format.
BR
Zoki
I wonder if I can use adafruit bme680 libraries since my chip is generic bme680 and the program has no adafruit bme680 identified. in this case, is there any other libraries for bme680 that I can use?
Hi.
Yes. You can use the adafruit libraries for the generic bme680. Ours is not from adafruit.
Regards,
Sara
Goodnight! Is it possible to create an alarm with the cards? For example: I want the gas sensor card to change the background color (red) and font color (white) when it is greater than a certain value and blink while the sensor value is above this value. Can you show me how I can do this?
Hi, If we want to change the color of the temperature box depending on a certain condition, for example if the temperature is higher than 30°C, the color changes to RED. Do we have to to this is the script file ? And can you give a hint on the code ? Thanks !
Hello… good afternoon
This tutorials is OK: the sketch compiled ok but i have this problem:
i use windows 11 with Firefox but the html page is “NOT VISIBLE” with the message: “Il server 192.168.0.6 sta impiegando troppo tempo a rispondere.” But the sketch is running: the value BME680 are writted on serial monitor.
With cellular RED_MI_NOTE_11 identical message.
Microsoft Edge: 192.168.0.6 ha richiesto troppo tempo per rispondere
With cellular TCL_20 is “OK !!!! and the HTML page is OK.
With cellular LG K9 is “OK” !!! and the HTML page is ok.
WHY ??? Sketch compiled with arduino 1.8.19 is ok.
Pardon my little english.
Best regards: wait for respons. Thank you
G.Valenti Trento (Italy)
Hi,
There is a new Drop-In Replacement BME688, could you update this tutorial?
and can you combine this tutorial with the Weather Station PCB, or simply add a display (CYD?) so that you can see the data both on Browser and on device itself as stand alone weather station.
Hello
I followed your logic wrote a dimple code to test my BME680. It’s very odd that nothing showing up in the serial monitor. I have tested many things, including different BME680, different ESP32, I2C scanner, rsisters (5.1k and 10k). Nothing worked. With the I2C scanner, it can identify device at 76. What could be wrong? Thanks a lot.
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME680.h>
Adafruit_BME680 bme; // I2C
void setup() {
Serial.begin(115200);
delay(2000); // Small delay to ensure stable serial communication
Serial.println(“Starting BME680 test…”);
// Initialize the BME680 sensor
if (!bme.begin(0x76)) { // Try 0x76 address first
Serial.println(“Could not find a valid BME680 sensor, check wiring!”);
while (1);
}
Serial.println(“BME680 initialization successful!”);
}
void loop() {
// Perform a sensor reading
if (!bme.performReading()) {
Serial.println(“Failed to perform reading :(“);
return;
}
// Display sensor readings
Serial.print(“Temperature = “);
Serial.print(bme.temperature);
Serial.println(” *C”);
Serial.print(“Pressure = “);
Serial.print(bme.pressure / 100.0);
Serial.println(” hPa”);
Serial.print(“Humidity = “);
Serial.print(bme.humidity);
Serial.println(” %”);
Serial.print(“Gas = “);
Serial.print(bme.gas_resistance / 1000.0);
Serial.println(” KOhms”);
delay(2000); // Delay between readings
}