IoT based Air Pollution Monitoring System using Arduino

Published  December 10, 2016   76
IOT based Air Pollution Monitoring System using Arduino

In this project we are going to make an IoT Based Air Pollution Monitoring System in which we will monitor the Air Quality over a webserver using internet and will trigger a alarm when the air quality goes down beyond a certain level, means when there are sufficient amount of harmful gases are present in the air like CO2, smoke, alcohol, benzene and NH3. It will show the air quality in PPM on the LCD and as well as on webpage so that we can monitor it very easily.

Previously we have built the LPG detector using MQ6 sensor, Smoke detector using MQ2 sensor, and Air Quality Analyser but this time we have used MQ135 sensor as the air quality sensor which is the best choice for monitoring Air Quality as it can detects most harmful gases and can measure their amount accurately. In this IOT project, you can monitor the pollution level from anywhere using your computer or mobile. We can install this system anywhere and can also trigger some device when pollution goes beyond some level, like we can switch on the Exhaust fan or can send alert SMS/mail to the user.

 

Required Components:

  • MQ135 Gas sensor
  • Arduino Uno
  • Wi-Fi module ESP8266
  • 16X2 LCD
  • Breadboard
  • 10K potentiometer
  • 1K ohm resistors
  • 220 ohm resistor
  • Buzzer

You can buy all the above components from here.

 

Circuit Diagram and Explanation:

First of all we will connect the ESP8266 with the Arduino. ESP8266 runs on 3.3V and if you will give it 5V from the Arduino then it won’t work properly and it may get damage. Connect the VCC and the CH_PD to the 3.3V pin of Arduino. The RX pin of ESP8266 works on 3.3V and it will not communicate with the Arduino when we will connect it directly to the Arduino. So, we will have to make a voltage divider for it which will convert the 5V into 3.3V. This can be done by connecting three resistors in series like we did in the circuit. Connect the TX pin of the ESP8266 to the pin 10 of the Arduino and the RX pin of the esp8266 to the pin 9 of Arduino through the resistors.

ESP8266 Wi-Fi module gives your projects access to Wi-Fi or internet. It is a very cheap device and make your projects very powerful. It can communicate with any microcontroller and it is the most leading devices in the IOT platform. Learn more about using ESP8266 with Arduino here.

Then we will connect the MQ135 sensor with the Arduino. Connect the VCC and the ground pin of the sensor to the 5V and ground of the Arduino and the Analog pin of sensor to the A0 of the Arduino.

Connect a buzzer to the pin 8 of the Arduino which will start to beep when the condition becomes true.

In last, we will connect LCD with the Arduino. The connections of the LCD are as follows

  • Connect pin 1 (VEE) to the ground.
  • Connect pin 2 (VDD or VCC) to the 5V.
  • Connect pin 3 (V0) to the middle pin of the 10K potentiometer and connect the other two ends of the potentiometer to the VCC and the GND. The potentiometer is used to control the screen contrast of the LCD. Potentiometer of values other than 10K will work too.
  • Connect pin 4 (RS) to the pin 12 of the Arduino.
  • Connect pin 5 (Read/Write) to the ground of Arduino. This pin is not often used so we will connect it to the ground.
  • Connect pin 6 (E) to the pin 11 of the Arduino. The RS and E pin are the control pins which are used to send data and characters.
  • The following four pins are data pins which are used to communicate with the Arduino.

Connect pin 11 (D4) to pin 5 of Arduino.

Connect pin 12 (D5) to pin 4 of Arduino.

Connect pin 13 (D6) to pin 3 of Arduino.

Connect pin 14 (D7) to pin 2 of Arduino.

  • Connect pin 15 to the VCC through the 220 ohm resistor. The resistor will be used to set the back light brightness. Larger values will make the back light much more darker.
  • Connect pin 16 to the Ground.

Iot-air-quality-monitoring-system-using-arduino-circuit

 

Working Explanation:

The MQ135 sensor can sense NH3, NOx, alcohol, Benzene, smoke, CO2 and some other gases, so it is perfect gas sensor for our Air Quality Monitoring Project. When we will connect it to Arduino then it will sense the gases, and we will get the Pollution level in PPM (parts per million). MQ135 gas sensor gives the output in form of voltage levels and we need to convert it into PPM. So for converting the output in PPM, here we have used a library for MQ135 sensor, it is explained in detail in “Code Explanation” section below.

Sensor was giving us value of 90 when there was no gas near it and the safe level of air quality is 350 PPM and it should not exceed 1000 PPM. When it exceeds the limit of 1000 PPM, then it starts cause Headaches, sleepiness and stagnant, stale, stuffy air and if exceeds beyond 2000 PPM then it can cause increased heart rate and many other diseases.

When the value will be less than 1000 PPM, then the LCD and webpage will display “Fresh Air”.  Whenever the value will increase 1000 PPM, then the buzzer will start beeping and the LCD and webpage will display “Poor Air, Open Windows”. If it will increase 2000 then the buzzer will keep beeping and the LCD and webpage will display “Danger! Move to fresh Air”.

 

Code Explanation:

Before beginning the coding for this project, we need to first Calibrate the MQ135 Gas sensor. There are lots of calculations involved in converting the output of sensor into PPM value, we have done this calculation before in our previous Smoke Detector project. But here we are using the Library for MQ135, you can download and install this MQ135 library from here: https://github.com/GeorgK/MQ135.

Using this library you can directly get the PPM values, by just using the below two lines:

MQ135 gasSensor = MQ135(A0);
float air_quality = gasSensor.getPPM();

But before that we need to calibrate the MQ135 sensor, for calibrating the sensor upload the below given code and let it run for 12 to 24 hours and then get the RZERO value.

#include "MQ135.h"
void setup (){
Serial.begin (9600);
}
void loop() {
MQ135 gasSensor = MQ135(A0); // Attach sensor to pin A0
float rzero = gasSensor.getRZero();
Serial.println (rzero);
delay(1000);
}

After getting the RZERO value. Put the RZERO value in the library file you downloaded "MQ135.h": #define RZERO 494.63

 

Now we can begin the actual code for our Air quality monitoring project.

In the code, first of all we have defined the libraries and the variables for the Gas sensor and the LCD. By using the Software Serial Library, we can make any digital pin as TX and RX pin. In this code, we have made Pin 9 as the RX pin and the pin 10 as the TX pin for the ESP8266. Then we have included the library for the LCD and have defined the pins for the same. We have also defined two more variables: one for the sensor analog pin and other for storing air_quality value.

#include <SoftwareSerial.h>
#define DEBUG true
SoftwareSerial esp8266(9,10); 
#include <LiquidCrystal.h> 
LiquidCrystal lcd(12,11, 5, 4, 3, 2);
const int sensorPin= 0;
int air_quality;

Then we will declare the pin 8 as the output pin where we have connected the buzzer. lcd.begin(16,2) command will start the LCD to receive data and then we will set the cursor to first line and will print the ‘circuitdigest’. Then we will set the cursor on the second line and will print ‘Sensor Warming’.

pinMode(8, OUTPUT);
lcd.begin(16,2);
lcd.setCursor (0,0);
lcd.print ("circuitdigest ");
lcd.setCursor (0,1);
lcd.print ("Sensor Warming ");
delay(1000);

 

Then we will set the baud rate for the serial communication. Different ESP’s have different baud rates so write it according to your ESP’s baud rate. Then we will send the commands to set the ESP to communicate with the Arduino and show the IP address on the serial monitor.

Serial.begin(115200);
esp8266.begin(115200);
  sendData("AT+RST\r\n",2000,DEBUG);
  sendData("AT+CWMODE=2\r\n",1000,DEBUG);
  sendData("AT+CIFSR\r\n",1000,DEBUG);
  sendData("AT+CIPMUair_quality=1\r\n",1000,DEBUG);
  sendData("AT+CIPSERVER=1,80\r\n",1000,DEBUG);
pinMode(sensorPin, INPUT);
lcd.clear();

 

For printing the output on the webpage in web browser, we will have to use HTML programming. So, we have created a string named webpage and stored the output in it. We are subtracting 48 from the output because the read() function returns the ASCII decimal value and the first decimal number which is 0 starts at 48.

if(esp8266.available())
  {
    if(esp8266.find("+IPD,"))
    {
     delay(1000);
     int connectionId = esp8266.read()-48;  
     String webpage = "<h1>IOT Air Pollution Monitoring System</h1>";
       webpage += "<p><h2>";   
       webpage+= " Air Quality is ";
       webpage+= air_quality;
       webpage+=" PPM";
       webpage += "<p>";

 

The following code will call a function named sendData and will send the data & message strings to the webpage to show.

     sendData(cipSend,1000,DEBUG);
     sendData(webpage,1000,DEBUG);
     
     cipSend = "AT+CIPSEND=";
     cipSend += connectionId;
     cipSend += ",";
     cipSend +=webpage.length();
     cipSend +="\r\n";

 

The following code will print the data on the LCD. We have applied various conditions for checking air quality, and LCD will print the messages according to conditions and buzzer will also beep if the pollution goes beyond 1000 PPM.

lcd.setCursor (0, 0);
lcd.print ("Air Quality is ");
lcd.print (air_quality);
lcd.print (" PPM ");
lcd.setCursor (0,1);
if (air_quality<=1000)
{
lcd.print("Fresh Air");
digitalWrite(8, LOW);

 

Finally the below function will send and show the data on the webpage. The data we stored in string named ‘webpage’ will be saved in string named ‘command’. The ESP will then read the character one by one from the ‘command’ and will print it on the webpage.

String sendData(String command, const int timeout, boolean debug)
{
    String response = ""; 
    esp8266.print(command); // send the read character to the esp8266
    long int time = millis();
    while( (time+timeout) > millis())
    {
      while(esp8266.available())
      {
        // The esp has data so display its output to the serial window 
        char c = esp8266.read(); // read the next character.
        response+=c;
      }  
    }
    if(debug)
    {
      Serial.print(response);
    }
    return response;
}

 

Testing and Output of the Project:

Before uploading the code, make sure that you are connected to the Wi-Fi of your ESP8266 device. After uploading, open the serial monitor and it will show the IP address like shown below.

IOT-getting-localserver-IP

 

Type this IP address in your browser, it will show you the output as shown below. You will have to refresh the page again if you want to see the current Air Quality Value in PPM.

Iot-air-quality-monitoring-system-output

We have setup a local server to demonstrate its working, you can check the Video below. But to monitor the air quality from anywhere in the world, you need to forward the port 80 (used for HTTP or internet) to your local or private IP address (192.168*) of you device. After port forwarding all the incoming connections will be forwarded to this local address and you can open above shown webpage by just entering the public IP address of your internet from anywhere. You can forward the port by logging into your router (192.168.1.1) and find the option to setup the port forwarding.

Code

#include "MQ135.h"
#include <SoftwareSerial.h>
#define DEBUG true
SoftwareSerial esp8266(9,10); // This makes pin 9 of Arduino as RX pin and pin 10 of Arduino as the TX pin
const int sensorPin= 0;
int air_quality;
#include <LiquidCrystal.h> 
LiquidCrystal lcd(12,11, 5, 4, 3, 2);

void setup() {
pinMode(8, OUTPUT);
lcd.begin(16,2);
lcd.setCursor (0,0);
lcd.print ("circuitdigest ");
lcd.setCursor (0,1);
lcd.print ("Sensor Warming ");
delay(1000);
Serial.begin(115200);
esp8266.begin(115200); // your esp's baud rate might be different
  sendData("AT+RST\r\n",2000,DEBUG); // reset module
  sendData("AT+CWMODE=2\r\n",1000,DEBUG); // configure as access point
  sendData("AT+CIFSR\r\n",1000,DEBUG); // get ip address
  sendData("AT+CIPMUair_quality=1\r\n",1000,DEBUG); // configure for multiple connections
  sendData("AT+CIPSERVER=1,80\r\n",1000,DEBUG); // turn on server on port 80
pinMode(sensorPin, INPUT);        //Gas sensor will be an input to the arduino
lcd.clear();
}

void loop() {

MQ135 gasSensor = MQ135(A0);
float air_quality = gasSensor.getPPM();

if(esp8266.available()) // check if the esp is sending a message 
  {
    if(esp8266.find("+IPD,"))
    {
     delay(1000);
     int connectionId = esp8266.read()-48; /* We are subtracting 48 from the output because the read() function returns the ASCII decimal value and the first decimal number which is 0 starts at 48*/ 
     String webpage = "<h1>IOT Air Pollution Monitoring System</h1>";
       webpage += "<p><h2>";   
       webpage+= " Air Quality is ";
       webpage+= air_quality;
       webpage+=" PPM";
       webpage += "<p>";
     if (air_quality<=1000)
{
  webpage+= "Fresh Air";
}
else if(air_quality<=2000 && air_quality>=1000)
{
  webpage+= "Poor Air";
}

else if (air_quality>=2000 )
{
webpage+= "Danger! Move to Fresh Air";
}

webpage += "</h2></p></body>"; 
     String cipSend = "AT+CIPSEND=";
     cipSend += connectionId;
     cipSend += ",";
     cipSend +=webpage.length();
     cipSend +="\r\n";
     
     sendData(cipSend,1000,DEBUG);
     sendData(webpage,1000,DEBUG);
     
     cipSend = "AT+CIPSEND=";
     cipSend += connectionId;
     cipSend += ",";
     cipSend +=webpage.length();
     cipSend +="\r\n";
     
     String closeCommand = "AT+CIPCLOSE="; 
     closeCommand+=connectionId; // append connection id
     closeCommand+="\r\n";
     
     sendData(closeCommand,3000,DEBUG);
    }
  }

lcd.setCursor (0, 0);
lcd.print ("Air Quality is ");
lcd.print (air_quality);
lcd.print (" PPM ");
lcd.setCursor (0,1);
if (air_quality<=1000)
{
lcd.print("Fresh Air");
digitalWrite(8, LOW);
}
else if( air_quality>=1000 && air_quality<=2000 )
{
lcd.print("Poor Air, Open Windows");
digitalWrite(8, HIGH );
}
else if (air_quality>=2000 )
{
lcd.print("Danger! Move to Fresh Air");
digitalWrite(8, HIGH);   // turn the LED on
}
lcd.scrollDisplayLeft();
delay(1000);
}
String sendData(String command, const int timeout, boolean debug)
{
    String response = ""; 
    esp8266.print(command); // send the read character to the esp8266
    long int time = millis();
    while( (time+timeout) > millis())
    {
      while(esp8266.available())
      {
        // The esp has data so display its output to the serial window 
        char c = esp8266.read(); // read the next character.
        response+=c;
      }  
    }
    if(debug)
    {
      Serial.print(response);
    }
    return response;
}

Video

Comments

Submitted by navakarthiga r… on Thu, 03/02/2017 - 14:30

Permalink

Haii sir/mam ,i am doing 3rd year engg .i need a clear explanation and video for connecting the equipments of this air pollution monitoring system for my mini project contest.plz tell me in detail as soon as possible.

please can you give me help on the code ? i mean if it is possible to use different lcd and how to make it work?

hello i am doing this your project as my final year project please can you give me the whole project? need your help please

Hello Pranjal,

Can you please give me the whole project? I need it for a subject at Uni and would be really helpful if I can use your project as an example.

Thank you.

Submitted by vinothini on Fri, 03/10/2017 - 10:25

Permalink

hi sir/mam...i am doing electronics and communication 3rd year...i need a clear arduino code in this project......because u given code is incorrect...so it is had error for arduino software....pls give a correct code...thanking you sir/mam...

Submitted by Abhijeet Singh on Fri, 04/28/2017 - 17:04

Permalink

Respected sir,
I am a graduated student. I went through your project and assemble the parts as you have shown. But it is not working. I wanted to contact you but didn't found any way to contact. Please reply ASAP.
Thank You.

Submitted by Manthan on Sat, 04/29/2017 - 23:35

Permalink

please, give correct code for esp8266 module particular in this project. i have successfully run full code,but show the error for wifi module is given to the below. give reply fastly.
deprecated conversion from string constant to 'char*' [-Wwrite-strings]

if(esp8266.find("+IPD,"))

Submitted by Roop on Mon, 05/08/2017 - 14:38

Permalink

While calibrating the sensor(MQ-135) the serial output is " inf " (after 6 hours of leaving it as it is) can someone please tell me what could be the problem.
regards
Roop

Submitted by Rounak Priyam … on Fri, 06/09/2017 - 20:19

Permalink

Sir can u please upload detailed pictures of the project.and the programme is also not working correctly so can you help me out with this...
it would be great if you respond..
thank you sir

Submitted by Hari on Mon, 08/21/2017 - 16:02

Permalink

Hi,
How you made your ESP 8266 to connect to WIFI and what is the AT command used in the code to make a connection to wifi network.

Submitted by irfanzainur on Sun, 09/10/2017 - 10:16

Permalink

Hi,
How you made your ESP 8266 to connect to WIFI and what is the AT command used in the code to make a connection to wifi network.

Submitted by hepshiba beula on Sun, 10/15/2017 - 21:11

Permalink

my code has been uploaded successfully but i didn't get anything on the serial monitor.could you help me??

Submitted by maginhawa on Wed, 11/08/2017 - 09:42

Permalink

Hello there. We would like to use this as our project for this coming finals. We would like to ask for your help regarding this. Do you have any videos on how you connected everything (wires and configurations)? If none, maybe at least the step by step procedures?

Thank you so much. Your help would be so much appreciated

Submitted by maginhawa on Sat, 11/25/2017 - 12:44

Permalink

The Reading I Get in the lcd whenever I put some smoke(cigarette and candle smokes) below the gas sensor is 0. something PPM is something wrong in my gas sensor? but in normal cases the reading i get in the lcd is ranges from 440 PPM to 450 PPM. Whats wrong?

Submitted by chichay on Wed, 11/29/2017 - 11:29

Permalink

The whole device already works: lcd, buzzer, gas sensor already calibrated, the webpage. However, I have the same problem with what maginhawa is experiencing. I placed the gas sensor near a burnt paper. The LCD shows a result of 0 and above. I expect it to be higher than 500, but it turns out to be the opposite. What seems to be the problem?

Thank you for answering. :)

Submitted by beauty on Thu, 12/07/2017 - 15:02

Permalink

pls i need a complete project on air and sound pollution monitoring
am presently working on it but the wifi module is not communicating with any website
what could be the problem?

Submitted by chichay on Thu, 01/11/2018 - 23:28

Permalink

The whole project is working now. We just had a wrong connection in our gas sensors A0. But the only problem we always have is the wifi module. It shows a signal (telling that the module still works) but won't transmit any data. It does not even respond to the at commands even if we changed the baud rates already. The browser would always say that "192.168.4.1 refuses to connect"

Please help us. And thank you so much for answering all of my questions.

Submitted by Jim on Sun, 01/14/2018 - 03:01

Permalink

Great project Muhammad, However as far as I can see there is a difference between your description and the diagram. On the diagram "RX" goes through one "resistor" to pin 9 where as in the description you say "resistors". In the diagram is shows the RX connected to ground through two resistors, where as in the description you make no mention of that. Can you please clarify. Thanks.

Arduino works on 5V and ESP on 3.3V. So when the Tx pin of Arduino is connected to Rx pin of ESP8266, the 5V signal from arduino might affect he ESP8266 module. 

So muhammad has used a resistor (potential divider) network to convert 5V from arduino to 3.3V. However these resistors are not mandatory as I have tested them to work even without them. To be on the safe side you can use these resistors (one from arduino to esp (R1) and the other from ESP to ground (R2)). The value of R1 and R2 could be 1K and 2K respectivly 

You can ignore the two resistors shown in the circuit diagram.

Submitted by arpit on Mon, 01/22/2018 - 22:30

Permalink

Has anyone made the complete project. Kindly help me with the code. Need urgent help.

Submitted by chiichay on Wed, 01/24/2018 - 10:06

Permalink

I hope you know the answer to this. Our serial monitor shows that our wifi module replies with the AT commands. But when i try to access its ip address, instead of showing the content we coded in the IDE, our webpage is blank or says 192.168.4.1 didnt send any data

Submitted by Anusha on Mon, 01/29/2018 - 07:08

Permalink

What are the technologies used and how many modules used in this project

4 Modules are used they are 

  • MQ135 Gas sensor
  • Arduino Uno
  • Wi-Fi module ESP8266
  • 16X2 LCD

Its explained in the materials required section also take a look at the circuit diagram 

Submitted by priya on Thu, 02/15/2018 - 10:24

Permalink

How to connect ESP8266 to WiFi ?
I have uploaded the code and getting an error like this:
//warning: espcomm_sync failed
error: espcomm_open failed
error: espcomm_upload_mem failed
error: espcomm_upload_mem failed//

Can you please help me in resolving the error?

Submitted by Sonali Lokare on Tue, 03/13/2018 - 21:27

Permalink

Hello sir, we are third year student we want an info about how sensor is calibrated and how we find the value of rzero & where it is placed in program.

Submitted by Sankaranarayanan.S on Tue, 03/13/2018 - 21:42

Permalink

Hello Sir,I am studying. 3 rd CSE.I wish to do this. Project as my mini project. So please give me more details about this project and also provide a full video how to connect this full circuit immediately

Submitted by Delroy D'Souza on Fri, 03/30/2018 - 09:29

Permalink

For those getting Esp8266 error change this line
sendData("AT+CIPMUair_quality=1\r\n",1000,DEBUG); // configure for multiple connections
To
sendData("AT+CIPMUX=1\r\n",1000,DEBUG); // configure for multiple connections
You only need to change AT+CIPMUX and remove the air_quality. The page will be displayed 100% in your browser

Submitted by arpit on Sat, 03/31/2018 - 17:15

Permalink

There are gibberish values being shown in the serial monitor and although it gives the IP address to open the webpage, but in the end it shows "error" instead of "ok". Can someone help with this.

Submitted by Delroy D'Souza on Wed, 04/11/2018 - 20:22

In reply to by arpit

Permalink

Change this line sendData("AT+CIPMUair_quality=1\r\n",1000,DEBUG); // configure for multiple connections
To this
sendData("AT+CIPMUX=1\r\n",1000,DEBUG); // configure for multiple connections

Submitted by Chairul Arifin on Wed, 05/30/2018 - 05:18

Permalink

hello, i want to ask. are i need to use XAMPP to activate apache to use web server? what is required also php file for the "webpage" and "command" ? or i just need to follow the step above? if the file is needed where can i get it?

thank you

Submitted by Anish Shetty on Tue, 07/03/2018 - 16:43

Permalink

hi, the code given above shows no error but in serial monitor i am getting a error once the ip address is shown i am getting a error. even the ip address 192.168.4.1 is not opening and am not getting any readings too. may i get some solution for the same i need to know if i have missed some steps because i have followed all the steps. reply as soon as possible i have a deadline to submit this project. thank you

Submitted by anne on Sat, 07/07/2018 - 11:54

Permalink

Hi, I'm planning to make this project. Can someone help me if i use a gsm module instead of wifi module so the user can be notified through sms. Thank you so much!

when i connect esp8266 with the arduino i can't find port for esp8266. and espcomm upload mem failed error occurs while uploding the code.

Hi everybody, i need  urgent help. My problem is After uploading the program if i open the serial monitor the following  message will be displayed on the serial monitor.

AT+RST
OK ets Jan  8 1013,rst cause:2, boot mode:(3,0)

load 0x40100000,otail 0
chksum 0x63
load 0x3fge8,
tail 0
chkal
tail 0u
nez aM

-Thhnker Technology Co. Ltd/

ready
AT+CWS⸮TZ⸮e
C⸮j⸮L⸮AJ+CIFSR
+CIFSR:APHP,"192.168.4.1"
+CIFSR;APMAC,"82:7d:3a:4d:d3:AT+CIPMUlOL⸮$⸮D⸮m⸮H⸮AT+CIPSERVDR=1,80
OK

If i type the IP Address 192.168.4.1 on the browser. I get the following message

This site can’t be reached

192.168.4.1 took too long to respond.

Try:

ERR_CONNECTION_TIMED_OUT
 
What might be the Problem ?.

 

Hello eveyone

Iam getting error on Lcd and i don't know the procedure

can any one please provide me step by step instruction please.....

Brother/Sir Please guide me if you can

Iam in a hurry in completing project

Thank you

 

 

Hello, Thanks for the nice project idea. I have noticed that you have mentioned that RX pin of the esp8266 to the pin 9 of Arduino, and TX Pin of ESP8266 to pin 10 of Arduino. However, in the diagram (Image) pin connections are alternate.

Please let me know if which statement to be considered? Thanks in advance.