How to Build a Mini Air Quality Monitoring System using ESP32

Written by malhaaar | Published 2022/03/07
Tech Story Tags: iot | pollution | air-pollution | air-quality-monitoring-system | diy-iot | esp32 | arduino | arduino-tutorial

TLDRThis is a mini IOT based air quality monitoring system that will monitor the air quality over a webserver using the internet. It will monitor and alert users as and when the levels cross a specified limit. The MQ135 gas sensor is used which will give us output in the form of voltage levels and we convert it into PPM (parts per million). Real time PPM values can also be viewed in the Arduino Serial Monitor. The sensor is capable of sensing gases like NH3, NOx, alcohol, Benzene, smoke, CO2 and other harmful gases.via the TL;DR App

Nowadays, most of us out there face the problem of impure air quality due to the increase in pollutants and impurities mixed with the air. Pollutants like CO2, CO, CH4 emitted from vehicles and SO2, SO4 and other gases emitted from industries add to the amount of impurity in the air. Also, fireworks and crackers during festive seasons, occasions and events further increase the pollution level in the atmosphere.
As a result of this, various health-related and respiratory issues are also increasing among the common masses.
So to keep a track of the air quality around you, this is a mini IoT based air quality monitoring system that will monitor the air quality over a web server using the internet and alarm or trigger if the air quality goes poorer than a certain level, i.e. if there are sufficient amount of harmful gases present in the air. It shows the air quality in PPM on the LCD as well as on the webpage so that you can monitor it easily.

Objective

  • To measure and monitor the air pollution levels
  • To detect highly polluted conditions
  • To alert user as and when the levels cross a specified limit

Components you'll require

  • ESP32 system on a chip microcontroller
  • MQ135 gas sensor
  • LEDs
  • Resistors
  • Buzzer
  • Some wires and a breadboard

Block Diagram

Circuitry

Software Used

Arduino IDE

Working

  1. Make the connections as per the circuit diagram above.
  2. Connect the ESP32 with your computer/laptop. Select a suitable port and Esp32 board and hit 'Upload' to upload the code into the ESP32.
    (I’ve used the MQ135 gas sensor here which is basically a Air Quality sensor capable of sensing gases like NH3, NOx, alcohol, Benzene, smoke, CO2 and other harmful gases. MQ135 will sense the gases and we will get the Pollution/Air quality level in PPM (parts per million). The MQ135 sensor will give us output in form of voltage levels and we convert it into PPM (our code and the module libraries will take care of that).
    For this project, I’ve set good air quality levels upto 800 PPM, poor levels in between 800 to 2000 and alert us if it exceeds 2000 PPM. )
  3. Provide the sensor with different types of smoke inputs and observe the output PPM levels in the web browser. All the web browser implementation is taken care by the code.
  4. Real time PPM values can also be viewed/observed in the Arduino IDE Serial Monitor. Just paste the IP address in the web browser and observe the PPM levels.
  5. Green LED will be ON until the PPM level is 800, Red LED will be ON post 800 mark and Red LED with Buzzer will be ON post 2000 mark.

Code

#include "MQ135.h"
#include <WiFi.h>
#include <Wire.h>

int air_quality;

const char* ssid     = "Enter your wifi";           //Replace with your network name
const char* password = "Enter your wifi password";  //Replave with your network 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() {
  delay(1000);
  Serial.begin(115200);
  pinMode(12, OUTPUT);       //Buzzer will be output to ESP32  
  pinMode(18, OUTPUT);       //Green Led will be Output to ESP32
  pinMode(19, OUTPUT);       //Red Led will be output to ESP32
  pinMode(34, INPUT);        //Gas sensor will be an input to the ESP32
  digitalWrite(18, HIGH);    
  digitalWrite(19, HIGH);
  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() {

  MQ135 gasSensor = MQ135(34);
  float air_quality = gasSensor.getPPM();
  
  if (air_quality >= 2000)
  {
    digitalWrite(12, HIGH);   //Buzzer is ON
    digitalWrite(19, LOW);    //RED LED is ON	
    digitalWrite(18, HIGH);   //GREEN LED is OFF
    delay(1000);
    digitalWrite(12, LOW);
  }
  if (air_quality >800 && air_quality <2000) 
  {
    digitalWrite(12, LOW);     //Buzzer is OFF
    digitalWrite(19, LOW);     //RED LED is ON
    digitalWrite(18, HIGH);    //GREEN LED is OFF
    delay(1000);
    digitalWrite(12, LOW);
  }
  if (air_quality < 800)
  {
    digitalWrite(12, LOW);     //Buzzer is OFF
    digitalWrite(18, LOW);     //GREEN LED is ON
    digitalWrite(19, HIGH);    //RED LED id OFF
  }
  delay(100);
  Serial.print(air_quality);      
  Serial.println(" PPM");
  delay(200);


  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:black; font-weight: bold; padding: 1px; }");

            // Web Page Heading

             client.println("</style></head><body><h2>AIR POLLUTION MONITOR</h2>");
            if (air_quality < 800)
            {
              client.println("</style></head><body><h2>FRESH AIR!</h2>");
            }
            else if (air_quality >800 && air_quality <2000) 
            {
              client.println("</style></head><body><h2>POOR AIR :(</h2>");
            }
	    else if (air_quality >= 2000)
	    {
	      client.println("</style></head><body><h2>ALERT!TOXIC AIR!ALERT</h2>");
	    }
			
            client.println("<table><tr><th>MEASUREMENT</th><th>VALUE</th></tr>");
            client.println("<tr><td>Pollution PPM</td><td><span class=\"sensor\">");
            client.println(air_quality);
            client.println("</span></td></tr></table>");
            

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

}

Conclusion

This is how you can build a small scale air quality monitoring system of your own and in the process, learn about Arduino, ESP32, environmental impacts of pollutants etc. on the go.

Written by malhaaar | Hackernoon. Music anytime, anywhere, always.
Published by HackerNoon on 2022/03/07