Tejas ShahKavyashree P
Published © MIT

Atmospheric Air Analyser

A low cost air quality monitoring device created with an aim to detect pollution hotspots caused due to traffic jams or factory emissions.

IntermediateWork in progress3 days21,124
Atmospheric Air Analyser

Things used in this project

Hardware components

Arduino Nano R3
Arduino Nano R3
×1
NodeMCU ESP8266 Breakout Board
NodeMCU ESP8266 Breakout Board
×1
TGS2600
×1
TGS2602
×1
DHT11 Temperature & Humidity Sensor (4 pins)
DHT11 Temperature & Humidity Sensor (4 pins)
×1
MQ135
×1

Software apps and online services

ThingSpeak API
ThingSpeak API
Arduino IDE
Arduino IDE
Autodesk EAGLE CAD
Software used for designing the PCB which houses the sensors
Autodesk AutoCAD
Software used to design the hardware casing for the PCB (with sensors)

Hand tools and fabrication machines

3D Printer (generic)
3D Printer (generic)
Soldering iron (generic)
Soldering iron (generic)
Solder Wire, Lead Free
Solder Wire, Lead Free
Solder Flux, Soldering
Solder Flux, Soldering
Multitool, Screwdriver
Multitool, Screwdriver

Story

Read more

Custom parts and enclosures

PCB Files

Find the EAGLE CAD design files (.brd/.sch)

Board Image generated on EAGLE CAD

Schematics

Schematic 1

Simple Schematic diagram showing connections between various components

Code

Code to read and analyse Sensor data

Arduino
Upload this code to your Arduino Nano with the sensors connected to the relevant pins.
#include <ArduinoJson.h>

//Gas Sensor Pins
#define F2600 A1
#define MQ135 A2
#define F2602 A3

//Gas Sensor Load Resistance (RL)
#define RL_F2600 7.5
#define RL_MQ135 10
#define RL_F2602 7.5
    
/*2600 GASSES*/
float CO_A = 1.144997421;
float CO_B = -0.21687423;

float CH4_A = 1.05777824;
float CH4_B = -0.0795645;

/*2602 GASSES*/
float NH3_A = 0.92372844;
float NH3_B = -0.291578925;

float H2S_A = 0.38881036;
float H2S_B = -0.35010059;

float VOC_A = 0.3220722;
float VOC_B = -0.6007520;


/*MQ-135 GASSES*/
//MQ-135 CO2
float A_MQ135_CO2 = 112.89808; 
float B_MQ135_CO2 = -2.868463517;  


//MQ-135 NOx
float A_MQ135_NOx = 34.69756084;  
float B_MQ135_NOx = -3.422829698; 

void setup() 
{
Serial.begin(9600); // opens serial port, sets data rate 9600 bps
}

void loop() 
{
  //Refer to the documentation mentioned on this page to understand this better
  
  float VRL_F2600; 
  float Rs_F2600; 
  float Ro_F2600 = 11.26;
  float ratio_F2600;
   
  VRL_F2600 = analogRead(F2600)*(5.0/1023.0); 
  Rs_F2600 = ((5.0/VRL_F2600)-1)*(RL_F2600);
  ratio_F2600 = Rs_F2600/Ro_F2600;


  float ppm_CO = CO_A * pow(ratio_F2600, CO_B);
  float ppm_CH4 = CH4_A * pow(ratio_F2600, CH4_B);

  float VRL_MQ135; 
  float Rs_MQ135; 
  float Ro_MQ135 = 20.1;
  float ratio_MQ135;

  VRL_MQ135 = analogRead(MQ135)*(5.0/1023.0); 
  Rs_MQ135 = ((5.0/VRL_MQ135)-1)*(RL_MQ135); 
  ratio_MQ135 = Rs_MQ135/Ro_MQ135;
  
  
  float ppm_CO2 = A_MQ135_CO2 * pow(ratio_MQ135, B_MQ135_CO2);
  float ppm_NOx = A_MQ135_NOx * pow(ratio_MQ135, B_MQ135_NOx);

  float VRL_F2602; 
  float Rs_F2602; 
  float Ro_F2602 = 64.88;
  float ratio_F2602;
   
  VRL_F2602 = analogRead(F2602)*(5.0/1023.0); 
  Rs_F2602 = ((5.0/VRL_F2602)-1)*(RL_F2602); 
  ratio_F2602 = Rs_F2602/Ro_F2602;

  float ppm_VOC = VOC_A * pow(ratio_F2602, VOC_B);
  float ppm_H2S = H2S_A * pow(ratio_F2602, H2S_B);  
  float ppm_NH3 = NH3_A * pow(ratio_F2602, NH3_B);
  
 //Refer to the author's website: https://arduinojson.org/ and read the documentation to understand ArduinoJSON better
  DynamicJsonBuffer jBuffer; 
  JsonObject& root = jBuffer.createObject();

  root["CO2"] = ppm_CO2;
  root["CO"] = ppm_CO;
  root["CH4"] = ppm_CH4;
  root["NOx"] = ppm_NOx;
  root["NH3"] = ppm_NH3;
  root["H2S"] = ppm_H2S;
  root["VOC"] = ppm_VOC;
  
  root.prettyPrintTo(Serial);
  Serial.println("");

//Minimum delay required for ThingSpeak to update is 16 seconds 
delay(16000);
}

Code to upload Sensor Data to ThingSpeak

Arduino
Upload this code to your NodeMCU. This will read data from the UART bus and send it to your ThingSpeak channel.
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
#include <SoftwareSerial.h>
#include "ThingSpeak.h"

SoftwareSerial mySerial(5, 4);
WiFiClient client; // Creating WiFiClient Object

//ThingSpeak Channel's API Keys
unsigned long myChannelNumber = enterChannelNumber;
const char * myWriteAPIKey = "enterYourWriteKey";

//Add your WiFi credentials here
#define WIFI_SSID "yourSSID"
#define WIFI_PASSWORD "yourPWD"


void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("connecting");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(100);
  }
  Serial.println();
  Serial.print("connected: ");
  Serial.println(WiFi.localIP());
  ThingSpeak.begin(client);
}

void loop() {
  // Check WiFi Status
  while (mySerial.available())
  {
    //To understand this section better, refer to the author: https://arduinojson.org/
    const size_t capacity = JSON_OBJECT_SIZE(7) + 100;
    DynamicJsonBuffer jsonBuffer(capacity);
    JsonObject& root = jsonBuffer.parseObject(mySerial);
    if (!root.success()) {
      Serial.println("parseObject() failed");
      return;
    }

    float CO2 = root["CO2"];
    float CO = root["CO"];
    float CH4 = root["CH4"];
    float NOx = root["NOx"];
    float NH3 = root["NH3"];
    float H2S = root["H2S"];
    float VOC = root["VOC"];

    Serial.print(CO2, 5);  Serial.print(",");
    Serial.print(CO, 5);  Serial.print(",");
    Serial.print(CH4, 5);  Serial.print(",");
    Serial.print(NOx, 5);  Serial.print(",");
    Serial.print(NH3, 5);  Serial.print(",");
    Serial.print(H2S, 5); Serial.print(",");
    Serial.println(VOC, 5);
//Sending Gas Data to ThingSpeak
    ThingSpeak.setField(1, CO2);
    ThingSpeak.setField(2, CO);
    ThingSpeak.setField(3, CH4);
    ThingSpeak.setField(4, NOx);
    ThingSpeak.setField(5, NH3);
    ThingSpeak.setField(6, H2S);
    ThingSpeak.setField(7, VOC);
    ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
  }
}

Code to find Ro Value

Arduino
Upload this code with one of the sensors connected to Nano and find the Ro value for that sensor
float RL = 10;  //The value of resistor RL 
float analog_value =0;
float VRL;
float Rs;
float Ro,k;

void setup() //Runs only once
{
Serial.begin(9600); //Initialise serial COM for displaying the value
}

void loop() 
{
for(int test_cycle = 1 ; test_cycle <= 200 ; test_cycle++) 
//Read the analog output of the sensor for 200 times

{
analog_value = analog_value + analogRead(A3); //add the values for 200
}

analog_value = analog_value/200.0;
Serial.print("Analog value at fresh air = ");
Serial.println(analog_value);

//Convert analog value to voltage
VRL = analogRead(A1)*(5.0/1023.0);

//RS = ((Vc/VRL)-1)*RL is the formulae we obtained from datasheet
Rs = ((5.0/VRL)-1) * RL;
Serial.print("Rs at fresh air = ");
Serial.println(Rs);

//Rs/Ro is k as we obtained from graph of datasheet
Ro = Rs/k;
Serial.print("Ro at fresh air = ");
Serial.println(Ro); //Display calculated Ro
delay(2500); 
}

My Github Rep

Find all source codes and files at my Github repository

Credits

Tejas Shah

Tejas Shah

1 project • 5 followers
Kavyashree P

Kavyashree P

1 project • 2 followers

Comments