Table of Contents

Air Quality Monitoring System using BMP280 Sensor

Ioan-Marian Dan-Hariton - SRIC

Demo: https://youtu.be/MTQ_KuXFTSU

Project Description

The purpose of this project is to collect data from a sensor and then display it on a screen attached to the board and also on a html page on localhost. The data is collected using a BMP280 sensor, sent to the ESP32 board and then from there, it is displayed on the attached display and also on the html page. The project also has the functionality to make a sound, from the attached buzzer, when the temperature is above 29°C.


Hardware Description

I used the following components in order to develop this project:

WEMOS LOLIN32 ESP32 specifications:

BMP280 specifications:

OLED Screen specifications:

Buzzer module specifications:

In order to connect all the components to the ESP32, we used in most part the SCL/22 and SDA/21 pins on the board. For connecting each component to board we did the following configuration: For BMP280:

For OLED Screen:

For Buzzer:

At first, the board was a little bit tricky because when I wanted to upload the code on it, there was an error “Wrong boot mode detected”. I searched for this error on google and I found a documentation which says:

“Depending on the kind of hardware you have, it may also be possible to manually put your ESP32 board into Firmware Download mode (reset). For development boards produced by Espressif, this information can be found in the respective getting started guides or user guides. For example, to manually reset a development board, hold down the Boot button (GPIO0) and press the EN button (EN (CHIP_PU)). For other types of hardware, try pulling GPIO0 down.”

As the board I used, WEMOS LOLIN32, has just one Reset button and not 2 buttons (Boot and EN), I had to pull the GPIO0 pin down (connect it to GND on the board) and then, after I pressed the Upload button in the Arduino IDE, I had to hold the Reset button until it appeared Connecting… in Arduino's console. After that, when I wanted to test the code uploaded on the board, I had to disconnect the GPIO0 pin from GND. This had to be done every time I uploaded a new version of code.


Software Description

For this to work, I had to set manually the I2C Address for the BMP280 sensor. Even if the object mySensor seems to be a BME280 instead of a BMP280, it still works as they are almost the same, the BME280 also reads humidity:

BME280 mySensor;
mySensor.setI2CAddress(0x76);

Also, another definitions are the ones for the screen and for the buzzer:

#define SCREEN_ADDRESS 0x3C
#define BUZZER_PIN 14

In the setup() function, there is the code for connecting to Wi-Fi and also the pin declaration for the buzzer:

 void setup()
{
Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  server.begin();

  pinMode(BUZZER_PIN, OUTPUT);
}

Also there is the function which displays the text on the screen:

 void testscrolltext(String pressure, String alt, String temp) {
  display.clearDisplay();

  display.setTextSize(1.5);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 3);
  display.println(pressure);
  display.println(alt);
  display.println(temp);
  display.display();
  delay(100);
} 

In the loop() function there is a part where the html page is created:

 if (currentLine.length() == 0) {
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();

            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:,\">");
            client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
            client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}</style></head>");
            
            client.println("<body><h1>BMP280 Sensor Data</h1>");
            
            testscrolltext(pressure, alt, temp);
            if(temp_2 < target_temp){
              digitalWrite(BUZZER_PIN, HIGH);
            }else{
              digitalWrite(BUZZER_PIN, LOW);
            }
            client.println("<script>");
            client.println("setTimeout(function() { location.reload(); }, 5000);");
            client.println("function updateData() {");
            client.println("var xhttp = new XMLHttpRequest();");
            client.println("xhttp.onreadystatechange = function() {");
            client.println("if (this.readyState == 4 && this.status == 200) {");
            client.println("var data = JSON.parse(this.responseText);");
            client.println(“document.getElementById('pressure').innerHTML = data.pressure;");
            client.println("document.getElementById('altitude').innerHTML = data.altitude;");
            client.println("document.getElementById('temperature').innerHTML = data.temperature;");
            client.println("}");
            client.println("};");
            client.println("xhttp.open('GET', '/data', true);");
            client.println("xhttp.send();");
            client.println("}");
            client.println("setInterval(updateData, 5000);");
            client.println("</script>");
            client.println("<p id='pressure'>" + pressure + "</p>");
            client.println("<p id='altitude'>" + alt + "</p>");
            client.println("<p id='temperature'>" + temp + "</p>");      
            
            client.println("</body></html>");
          
            client.println();
 

I had some difficulties synchronising the data that is showed on the web page with the one showed on the display, so values which are present on the display may differ from the values on the webpage.

The idea is that, because of the connection to the internet, the data is sent later to the web page, compared to the display where it is sent almost instantly.

For the development of this project, the following libraries have been used:


Conclusion

In conclusion, the scope of this project was to create an air quality monitoring system, by reading environment parameters such as temperature, pressure, altitude and send them to a web page and on a display. Also, the buzzer will make a sound when the temperature is above 29°C.


Bibliography