IoT Based Air Pollution Monitoring System – Arduino

In this post we are going to make couple of IoT based air pollution / air quality monitoring systems, one using Arduino and ESP8266 and another one using NodeMCU. The collected air quality data will be sent to Thingspeak where we can record and draw conclusions about the air quality in that surrounding area. We will also link the Thingspeak to twitter account to tweet automated air quality warnings if it goes beyond a pre-set value.

We will see:

  • Creating and setting up Thingspeak account.
  • Installing ESP8266 package.
  • IoT based air quality monitoring system using Arduino and ESP8266.
  • Circuit diagram and code.
  • IoT based air quality monitoring system using NodeMCU.
  • Circuit diagram and code.
  • Prototype of the proposed projects.
  • Data received on Thingspeak.
  • How to setup twitter account to send automated tweets about air quality?

Setting-up Thingspeak account for receiving air quality data:

  • First you need to create a Thingspeak account if you haven’t done yet.
  • Click “New channel” and do the following changes to your channel as shown below:
  • Scroll to the bottom of the page and click save channel.
  • Go to API keys tab and take note of your write API key which you need to enter it in the given code, also take note of your channel ID.
API Key
API Key

Now your new channel is ready to receive air pollution data which will be sent by the circuit after its construction.

Installing ESP8266 package to Arduino IDE:

To compile and upload the code to NodeMCU or to generic ESP8266 from Arduino IDE, you need to download ESP8266 package (core files), this can done by clicking this link and scrolling to the mentioned section. If have already done this you can skip this part.

IoT based air quality monitoring system using Arduino and ESP8266

Block diagram:

Block Diagram - IoT Based Air pollution Monitoring System

The above bock diagram shows how MQ135 air quality sensor’s data is sent to Thingspeak.

  • MQ135 is an analog air pollution sensor which converts the level of toxic gases in the surrounding to analog values.
  •  The Arduino collects the analog sensor values and converts it to digital value and sends it to ESP8266 via UART / serial communication.
  • The ESP8266 connects to Thingspeak server via internet. The sent data to Thingspeak can be accessed using a PC or a laptop by logging in to your Thingspeak account.   
  • Beside Arduino we have a 16 x 2 LCD to display real-time air pollution level and other stats about air quality sensor.  The LCD is connected to I2C adapter which will reduce the number of wires that connects from Arduino to LCD to four (VCC, GND, SDA and SCL).
I2C and LCD
I2C and LCD

How to upload code to generic ESP8266?

If you are a beginner in IoT one important thing you need to know is that the ESP8266 is a microcontroller board and it need to be programed to make it functional, only then it can send data to an intended destination server.

We are going to upload a program code written in Arduino IDE which enables your generic ESP8266 to connect to Thingspeak and also enabling its UART pins to receive numeric data from Arduino.

The generic ESP8266 doesn’t come with a USB port through which it connects to a PC, so we need an Arduino board (where the microcontroller IC can be removed temporarily) and you need to wire your ESP8266 as shown below to upload code:

Circuit diagram for uploading code to ESP8266
Circuit diagram for uploading code to ESP8266
Uploading code to ESP8266
Uploading code to ESP8266

After you wire-up your Arduino (with its IC removed) with ESP8266, follow the below instructions precisely:

  • Copy and paste the code for generic ESP8266 to the IDE.
  • Go to Tools > Board > Generic ESP8266.
  • Go to Tools > Upload speed > 115200.
  • Press and hold the flash button.
  • With another finger press the reset button once and release it.
  • After releasing the reset button only now release the flash button.
  • Now click upload, the code will be uploaded to ESP8266.

If you succeeded, you will see “done upload” message, if not you will see some error messages. If you failed try again after checking the wiring and pressing the buttons in the mentioned sequence.

Note: Generic ESP8266 uses 3.3V and applying 5V will kill the module.

Download Thingspeak library: Click here

Program code for generic ESP8266

// ----------(c) Electronics-project-hub-------- //
#include "ThingSpeak.h"
#include <ESP8266WiFi.h>

//------- WI-FI details ----------//
char ssid[] = "XXXXXXX";  // SSID here
char pass[] = "YYYYYYY"; // Password here
//--------------------------------//

//----------- Channel details ----------------//
unsigned long Channel_ID = 0000000; // Channel ID
const char * myWriteAPIKey = "ABCEDFG"; //Your write API key
//-------------------------------------------//

const int Field_Number = 1; // Don't change
String value = "";
int x;
WiFiClient  client;

void setup()
{
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  ThingSpeak.begin(client);
  internet();
}

void loop()
{
  internet();
  if (Serial.available() > 0)
  {
    while (Serial.available() > 0)
    {
      int inChar = Serial.read();
      value += (char)inChar;
    }
  }
  upload();
}

void internet()
{
  if (WiFi.status() != WL_CONNECTED)
  {
    while (WiFi.status() != WL_CONNECTED)
    {
      WiFi.begin(ssid, pass);
      delay(5000);
    }
  }
}

void upload()
{
  x = ThingSpeak.writeField(Channel_ID, Field_Number, value, myWriteAPIKey);
  if (x != 200)
  {
    delay(15000);
    upload();
  }
  value = "";
}
// ----------(c) Electronics-project-hub-------- //

You need to change the following in the code:

Enter your Wi-Fi details here:

//------- WI-FI details ----------//
char ssid[] = "XXXXXXX";  // SSID here
char pass[] = "YYYYYYY"; // Password here
//--------------------------------//

Enter you channel details here:

//----------- Channel details ----------------//
unsigned long Channel_ID = 0000000; // Channel ID
const char * myWriteAPIKey = "ABCEDFG"; //Your write API key
//-------------------------------------------//

Once you uploaded the code to ESP8266, you need to rewire the circuit as shown below:

IoT Based Air pollution Monitoring System Circuit

Note: Insert the microcontroller IC back to Arduino board’s socket.

Circuit description:

This is the final circuit using which we are going to obtain air quality readings and sending it to Thingspeak. The air quality is measured using MQ135 sensor as mentioned before, which can detect gases including NH3, NOx, alcohol, benzene, smoke and CO2.

Pin diagram of MQ135:

The rounded metallic mesh is the sensor and this module has four pins, we will be using only three: VCC, GND and Aout. Aout is the analog output of this sensor and Dout is not used here. MQ135 sensor need to reach an optimum temperature to detect the mentioned gases if not, the analog output will not be proportional to the level of gases present in its surrounding atmosphere.

When no gas is detected the output at Aout will be (ideally) zero and when some toxic gases is detected the output voltage will be proportional to the level of gas detected and if lot of toxic gas is detected the output shoots to 5V which is the maximum.

Arduino will gather the analog data from pin A0 (0 to 5V) where the MQ135 sensor is connected, the voltage range is converted to 0 to 1023 digital points and further 0 to 1023 is converted to percentage out of 100.

Arduino will send air quality data in percentage to its software serial (software UART) pins 10 and 11, these two pins are connected to UART pins of ESP8266.

Download LCD I2C library: Click here                              

Program code for Arduino

//---------(c) Electronics-project-hub.com ----------//
#include <SoftwareSerial.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
SoftwareSerial mySerial(10, 11);
float percent;
int raw;
void setup()
{
  mySerial.begin(115200); // Baud rate for ESP8266
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("IoT Air Quality");
  lcd.setCursor(0, 1);
  lcd.print("Monitor System");
  delay(2000);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("MQ135 sensor");
  lcd.setCursor(0, 1);
  lcd.print("is heating up...");
  for (int i = 0; i < 3; i++)
  {
    delay(20000);
    delay(20000);
    delay(20000);
  }
}

void loop()
{
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Air Pollution(%)");
  lcd.setCursor(0, 1);
  raw = analogRead(A0);
  percent = map(raw, 0, 1024, 1, 100);
  lcd.print(percent);
  lcd.print(" %");
  mySerial.println(percent); // Sending percents to ESP8266.
  delay(5000);
}
//---------(c) Electronics-project-hub.com ----------//

How to operate the above project?

  • With the completed project set-up plug the USB to a computer or to a power bank, we recommend a power bank so that you can power the circuit for several hours.
  • Turn on your Wi-Fi hotspot (turn your hotspot ON before you power the circuit); the SSID and password should be as same as you entered in the code.
  • The circuit will display a message saying to wait for some time so that the sensor can reach an optimum temperature. Please wait for 3 minutes and no strong air circulation should be present around the MQ135 sensor.
  • After 3 minutes LCD display will show air pollution in percentage: 0% is the minimum (best air quality) and 100% is the maximum (worst air quality). Always lower readings are the best.
  • Open your Thingspeak account and open private view, you will receive live data to your channel.

Data on Thingspeak:

Air pollution data on Thingspeak

Prototype:

IoT Based Air pollution Monitoring System
IoT Based Air pollution Monitoring System

Please note that the MQ135 sensor used for prototyping was without the breakout board so we did some additional wiring to make the sensor functional. Preferably you should buy a MQ135 sensor with the breakout board as shown in the pin diagram.

IoT based air pollution monitoring system using NodeMCU

In this section we are going to build IoT based air quality monitoring system using NodeMCU. Here we no need to upload two separate codes to two different microcontroller boards like what we did in the previous section.

NodeMCU can do many of the functions of an Arduino board and it has built-in ESP8266 based Wi-Fi module too. The program code for analog to digital conversion of MQ135 sensor data and sending the collected data to Thingspeak can be written in a single program code.

Block diagram:

Block Diagram - IoT Based Air pollution Monitoring System NodeMCU

Circuit diagram:

NodeMCU - IoT Based Air pollution Monitoring System Circuit

Circuit description:

The circuit is self-explanatory just wire the circuit as shown in the above schematic. In this circuit also will be using I2C adapter module for LCD display to reduce the number of wire connections.

NodeMCU’s I2C pins are D1 which is SCL and D2 which is SDA are connected to I2C adapter module.

The MQ135 sensor need 5V supply, you can connect its Vcc pin to “VU” pin of NodeMCU which outputs 5V. If you have a NodeMCU from a different manufacturer you can connect the Vcc of MQ135 to “Vin” pin of NodeMCU which can supply 5V.   

How to upload code to NodeMCU?

  • Connect the NodeMCU to your computer using USB cable.
  • Go to Tools > Board > NodeMCU 1.0
  • Go to Tools > Upload speed > 115200.
  • Press and hold the on-board flash button.
  • Press the reset button once and release it.
  • After releasing the reset button, release the flash button.
  • Click upload.  

Download Thingspeak library: Click here

Download LCD I2C library: Click here

Program code for NodeMCU:

// -----------(c) Electronics-project-hub ----------//
#include <LiquidCrystal_I2C.h>
#include "ThingSpeak.h"
#include <ESP8266WiFi.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

//----------- Enter you Wi-Fi Details---------//
char ssid[] = "xxxxxx";   // your network SSID (name)
char pass[] = "yyyyyy";   // your network password
//-------------------------------------------//

//----------- Channel Details -------------//
unsigned long Channel_ID = 00000; // Channel ID
const char * WriteAPIKey = "ABCDEF"; // Your write API Key
// ----------------------------------------//

const int Field_number = 1;
float value;
int raw;
WiFiClient  client;

void setup()
{
  WiFi.mode(WIFI_STA);
  ThingSpeak.begin(client);
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("IoT Air Quality");
  lcd.setCursor(0, 1);
  lcd.print("Monitor System");
  delay(2000);
  internet();
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("MQ135 sensor");
  lcd.setCursor(0, 1);
  lcd.print("is heating up...");
  for (int i = 0; i < 3; i++)
  {
    delay(20000);
    delay(20000);
    delay(20000);
  }
}

void loop()
{
  get_value();
  upload();
}

void get_value()
{
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Air Pollution(%)");
  lcd.setCursor(0, 1);
  raw = analogRead(A0);
  value = map(raw, 0, 1024, 1, 100);
  lcd.print(value);
  lcd.print(" %");
  delay(5000);
}

void internet()
{
  if (WiFi.status() == WL_CONNECTED)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Connected to");
    lcd.setCursor(0, 1);
    lcd.print("internet!");
    delay(2000);
  }
  if (WiFi.status() != WL_CONNECTED)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Connecting to");
    lcd.setCursor(0, 1);
    lcd.print(ssid);
    lcd.print(" SSID...");
    for (int i = 0; i < 5; i++)
    {
      WiFi.begin(ssid, pass);
      delay(5000);
    }
    if (WiFi.status() != WL_CONNECTED)
    {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("No internet");
      lcd.setCursor(0, 1);
      lcd.print("connection !");
      delay(3000);
    }
    else if (WiFi.status() == WL_CONNECTED)
    {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Connected to");
      lcd.setCursor(0, 1);
      lcd.print("internet!");
      delay(2000);
    }
  }
}

void upload()
{
  ThingSpeak.writeField(Channel_ID, Field_number, value, WriteAPIKey);
}
// -----------(c) Electronics-project-hub ----------//

You need to enter you Wi-Fi detains here:

//----------- Enter you Wi-Fi Details---------//
char ssid[] = "xxxxxx";   // your network SSID (name)
char pass[] = "yyyyyy";   // your network password
//-------------------------------------------//

You need to enter you channel details here:

//----------- Channel Details -------------//
unsigned long Channel_ID = 00000; // Channel ID
const char * WriteAPIKey = "ABCDEF"; // Your write API Key
// ----------------------------------------//

Note: You will get a warning message while compiling the above code and please ignore it. 

How to operate the above project?

Please refer the previous section’s operating instruction.

Data on Thingspeak

Air pollution data on Thingspeak

Prototype using NodeMCU:

NodeMCU - IoT Based Air pollution Monitoring System
NodeMCU - IoT Based Air pollution Monitoring System

How to send automated tweets when air quality gets bad?

This is an optional step which you can add to your project.

You can link your twitter account to Thingspeak and send automated tweets when the air pollution goes bad beyond a pre-set level. You can do this by following below steps:

Click Apps > ThingTweet and press link twitter account.

Linking Tweeter account with Thingspeak

Enter your twitter E-mail and password and click “Authorize App” button, you will see authorization success message.

Now click App > React

Click new react:

You’ll need to enter the details in the react page as shown below:

  • Click “save React” after you finish setting the conditions.

You can enter any value in the place of 35, if the air pollution goes above 35% a tweet will be sent from your twitter account. You can also play around with the other conditions available.

In “then tweet” section you can write anything you wish to tweet when the conditions are met. We recommend you to acknowledge this tweet as an automated one so that you and your followers can differentiate between tweets intentionally made by you and automated tweets like air quality warnings. 

Automated tweet:

If you have any questions regarding this project, you can ask us in the comment section and you will get a guaranteed reply from us.

Avatar photo

My nick name is blogthor, I am a professional electronics engineer specialized in Embedded System. I am a experienced programmer and electronics hardware developer. I am the founder of this website, I am also a hobbyist, DIYer and a constant learner. I love to solve your technical queries via comment section.