Measuring PPM from MQ Gas Sensors using Arduino (MQ-137 Ammonia)

Right from the time of industrial age, we mankind have been rapidly developing. With every progress we also pollute our environment and eventually degrading it. Now global warming is an alarming threat and even the air that we breathe are getting critical. So air quality monitoring has also started to gain importance. So in this article we will learn how to use any MQ series gas sensor with Arduino and showing the output in PPM (parts per million). PPM is also expressed as milligrams per litre (mg/L).

Measuring PPM from MQ Gas Sensors using Arduino (MQ-137 Ammonia)

MQ-series Gas sensors

  • Carbon Dioxide (CO2) : MG-811
  • Carbon Monoxide (CO): MQ-9
  • Total Volatile Organic Compounds (TVOCs): CCS811
  • Equivalent Carbon Dioxide (eCO2): CCS811
  • Metal Oxide (MOX): CCS811
  • Ammonia: MQ-137
  • Air Quality: MQ-135
  • LPG, Alcohol, Smoke: MQ2

We have already used MQ2 for smoke sensing and MQ-135 for Air quality monitoring project. Here I will be using the MQ-137 sensor from sainsmart to measure ammonia in ppm. With the sensor in hand I went through all the available tutorials and found that there has no proper documentation on how to measure the gas in ppm. Most tutorials either deal with only the Analog values or introduce some constants which are not reliable for measuring all type of gas.  So after fiddling around online for a long time I finally found how to use these MQ series gas sensors to measure ppm using Arduino. I am explaining things from the bottom without any libraries so that you can use this article for any Gas sensor available with you.

Preparing your Hardware:

The MQ gas sensors can either purchased as a module or just as a sensor alone. If your purpose is to measure only ppm then it’s best to buy the sensor alone since the module is good for only using the Digital pin. So if you have purchased the module already then you have to perform a small hack which will be discussed further. For now, let’s assume you have purchased the sensor.

As you can see you just have to connect one end of ‘H’ to supply and the other end of ‘H’ to ground. Then combine both A’s and both B’s. Connect one set to supply voltage and the other to your analog pin. The resistor RL plays a very important role in making the sensor work. So make a note of which value you are using, a value of 47k is recommended.

If you have already purchased a module, then you should track your PCB traces to find the value of your RL in the board. Grauonline has already done this work for us and the circuit diagram of the MQ gas sensor board is given below.

Measuring PPM from MQ Gas Sensors using Arduino (MQ-137 Ammonia) Schematic

As you can see the resistor R(R2) is connected between the Aout pin and the ground, so if you are having a module the value of Rcan be measured by using a multimeter in resistance mode across Vout pin and Vcc pin of the module. In my sainsmart MQ-137 gas sensor the value of RL was 1K and was located here as shown in the picture below.

As you can see the resistor RL (R2) is connected between the Aout pin and the ground, so if you are having a module the value of RL can be measured by using a multimeter in resistance mode across Vout pin and Vcc pin of the module. In my sainsmart MQ-137 gas sensor the value of RL was 1K and was located here as shown in the picture below.

However, the website claims that it provides a variable pot of RL which is not true as you can clearly see in the circuit diagram, the pot is used to set the variable voltage for op-amp and has nothing to do with RL. So we have to manually solder the SMD resistor (1K) shown above and we have to use our own resistor across the Ground and Vout pin which will act as RL. The best value for RL will be 47K as suggested by datasheet hence we are going to use the same.

Approach to Measure PPM from MQ Gas Sensors:

Now that we know the value of RL lets proceed on how to actually measure ppm from these sensors. Like all sensors the place to start is its datasheet. The MQ-137 Datasheet is given here but make sure you find the correct datasheet for your sensor. Inside the datasheet we are need only one graph which will be plotted against (Rs/Ro) VS PPM this is the one that we need for our calculations. So gab it and keep it someplace handy. The one for my sensor is shown below.

Approach to Measure PPM from MQ Gas Sensors:

Turns out that MQ137 sensor can measure NH3, C2H6O and even CO. But, here I am interested only in the values of NH3. However you can use the same method to calculate ppm for any sensor you like. This graph is the only source for us to find the value of ppm and if we could somehow calculate the ration of Rs/Ro (X-axis) we can use this graph to find the value of ppm (Y-axis). To find the value of Rs/Ro we need to find the value of Rs and the value of Ro. Where Rs is the Sensor resistance at gas concentration and Ro is the sensor resistance in clean sir.

Yess… this is the plan let’s see how we can get away with this….

Calculating the Value of Ro at Clean Air:

Note that in the graph value of Rs/Ro is constant for air (thick blue line) so we can use this to our advantage and say that when the sensor is working in fresh air the value of Rs/Ro will be 3.6 refer the picture below

Rs/Ro = 3.6

From the datasheet we also get to have a formula for calculating the value of Rs. The formula is shown below. If you are interested to know how this formula is derived you can read through jay con systems, I would also like to credit them in helping me to sort this out.

Formula for calculating the value of Rs

In this formula the value of Vc is our supply voltage (+5V) and the value of Ris the one that we calculated already (47K for my sensor). If we write a small Arduino program we could also find the value of VRL and finally calculate the value of Rs. I have given an Arduino Program below which reads the analog voltage (VRL) of the sensor and calculates the value of Rs using this formula and finally displays it in the serial monitor. The program is well explained through the comment section so I am skipping its explanation here so as to keep this article short.

/*
 * Program to measure the value of R0 for a know RL at fresh air condition
 * Program by: B.Aswinth Raj
 * Website: www.circuitdigest.com                                       
 * Dated: 28-12-2017
 */
//This program works best at a fresh air room with temperaure Temp: 20℃, Humidity: 65%, O2 concentration 21% and when the value of Rl is 47K

#define RL 47  //The value of resistor RL is 47K
void setup() //Runs only once
{
  Serial.begin(9600); //Initialise serial COM for displaying the value
}

void loop() {
  float analog_value;
  float VRL;
  float Rs;
  float Ro;
  for(int test_cycle = 1 ; test_cycle <= 500 ; test_cycle++) //Read the analog output of the sensor for 200 times
  {
    analog_value = analog_value + analogRead(A0); //add the values for 200
  }
  analog_value = analog_value/500.0; //Take average
  VRL = analog_value*(5.0/1023.0); //Convert analog value to voltage
  //RS = ((Vc/VRL)-1)*RL is the formulae we obtained from datasheet
  Rs = ((5.0/VRL)-1) * RL;
  //RS/RO is 3.6 as we obtained from graph of datasheet
  Ro = Rs/3.6;
  Serial.print("Ro at fresh air = ");
  Serial.println(Ro); //Display calculated Ro
  delay(1000); //delay of 1sec
}

Note: The value of Ro will be varying, allow the sensor to pre-heat at least for 10 hours and then use the value of Ro.

 RL is 47kΩ

 

I concluded the value of Ro to be 30KΩ for my sensor (when RL is 47kΩ). Yours might slightly vary.

Measure the value of Rs:

Now that we know the value of Ro we can easily calculate the value of Rs using the above two formulae. Note that the value of Rs that was calculated previously is for fresh air condition and it will not be the same when ammonia is present in the air. Calculating the value of Rs is not a big issue which we can directly take care in the final program.

Relating Rs/Ro ratio with PPM:

Now that we know how to measure the value of Rs and Ro we would be able to find its ratio (Rs/Ro). Then we can use the chart (shown below) to relate to the corresponding value of PPM.

Ro ratio with PPM

Although the NH3 line (cyan colour) appears to be linear it is actually not linear. The appearance is because the scale is divided un-uniformly for appearance.  So the relating between Rs/Ro and PPM is actually logarithmic which can be represented by the below equation.

log(y) = m*log(x) + b

where,
y = ratio (Rs/Ro)
x = PPM
m = slope of the line
b = intersection point

To find the values of m and b we have to consider two points (x1,y1) and (x2,y2) on our gas line. Here we are working with ammonia so the two points I have considered is (40,1) and (100,0.8) as shown in the picture above (marked as red) with red marking.

m = [log(y2) - log(y1)] / [log(x2) - log(x1)]
m = log(0.8/1) / log(100/40)
m = -0.243

Similarly for (b) let’s get the midpoint value (x,y) from the graph which is (70,0.75) as shown in picture above (marked in blue)

b = log(y) - m*log(x)
b = log(0.75) - (-0.243)*log(70)
b = 0.323

That’s it now that we have calculated the value of m and b we can equate the value of (Rs/Ro) to PPM using the below formula

PPM = 10 ^ {[log(ratio) - b] / m}

Program to calculate PPM using MQ sensor:

The complete program to calculate PPM using a MQ sensor is given below. Few important lines are explained below.

Before proceeding with the program we need to feed in the values of Load resistance (RL), Slope(m), Intercept(b) and the value of Resistance in fresh air (Ro). The procedure to obtain all these values have already be explained so let’s just feed them in now

#define RL 47  //The value of resistor RL is 47K
#define m -0.263 //Enter calculated Slope
#define b 0.42 //Enter calculated intercept
#define Ro 30 //Enter found Ro value

Then read the Voltage drop across the sensor (VRL) and convert it to Voltage (0V to 5V) since the analog read will only return values from 0 to 1024.

VRL = analogRead(MQ_sensor)*(5.0/1023.0); //Measure the voltage drop and convert to 0-5V

Now, that the value of VRL is calculated you can use the formula discussed above to calculate the value of Rs and the also the ratio (Rs/Ro)

ratio = Rs/Ro;  // find ratio Rs/Ro

Finally, we can calculate the PPM with our logarithmic formula and display it on our serial monitor as shown below

double ppm = pow(10, ((log10(ratio)-b)/m)); //use formula to calculate ppm
Serial.print(ppm); //Display ppm

Showing PPM value on Hardware with Arduino and MQ-137:

Enough of all the theory let us build a simple circuit with the sensor and LCD to display the value of gas in PPM. Here the sensor I am using is MQ137 which measures ammonia, the circuit diagram for my set up is shown below.

Showing PPM value on Hardware with Arduino and MQ-137

Connect your sensor and your LCD as shown in the Circuit diagram and upload the code given at the end of the program. You have to modify the Ro value as explained above. Also make the changes in parameter values if you are using any other resistor as RL other than 4.7K.

Leave your set-up powered for at least 2 hours before you take any readings, (48 hrs is recommended for more accurate values). This time is called the heating time, during which the sensor warms up. After this, you should be able to see the value of PPM and the voltage displayed on your LCD screen as shown below.

the value of PPM and the voltage displayed on your LCD screen

Now to ensure if the values are really related to the presence of ammonia, let’s place this set-up inside a closed container and send ammonia gas inside it to check if the values are increasing. I do not have a proper PPM meter with me calibrate it and it would great if someone with meter could test this set-up and let me know.

You can watch the video below to check how the readings varied based on the presence of ammonia. Hope you understood the concept and enjoyed learning it. If you have any doubts leave them in the comment section or for more detailed help use the forum here.

Code

/*
* Program to measure gas in ppm using MQ sensor
* Program by: B.Aswinth Raj
* Website: www.circuitdigest.com
* Dated: 28-12-2017
*/
#define RL 47  //The value of resistor RL is 47K
#define m -0.263 //Enter calculated Slope
#define b 0.42 //Enter calculated intercept
#define Ro 20 //Enter found Ro value
#define MQ_sensor A0 //Sensor is connected to A4

#include <LiquidCrystal.h> //Header file for LCD from https://www.arduino.cc/en/Reference/LiquidCrystal

const int rs = 8, en = 9, d4 = 10, d5 = 11, d6 = 12, d7 = 13; //Pins to which LCD is connected
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup() {
lcd.begin(16, 2); //We are using a 16*2 LCD display
lcd.print(“NH3 in PPM”); //Display a intro message
lcd.setCursor(0, 1);   // set the cursor to column 0, line 1
lcd.print(“-CircuitDigest”); //Display a intro message

delay(2000); //Wait for display to show info
lcd.clear(); //Then clean it
}

void loop() {

float VRL; //Voltage drop across the MQ sensor
float Rs; //Sensor resistance at gas concentration
float ratio; //Define variable for ratio

VRL = analogRead(MQ_sensor)*(5.0/1023.0); //Measure the voltage drop and convert to 0-5V
Rs = ((5.0*RL)/VRL)-RL; //Use formula to get Rs value
ratio = Rs/Ro;  // find ratio Rs/Ro

float ppm = pow(10, ((log10(ratio)-b)/m)); //use formula to calculate ppm

lcd.print(“NH3 (ppm) = “); //Display a ammonia in ppm
lcd.print(ppm);
lcd.setCursor(0, 1);   // set the cursor to column 0, line 1
lcd.print(“Voltage = “); //Display a intro message
lcd.print(VRL);

delay(200);
lcd.clear(); //Then clean it
}

Video:

Source: Measuring PPM from MQ Gas Sensors using Arduino (MQ-137 Ammonia)


About The Author

Ibrar Ayyub

I am an experienced technical writer with a Master's degree in computer science from BZU Multan University. I have written for various industries, mainly home automation and engineering. My writing style is clear and simple, and I am skilled in using infographics and diagrams. I am a great researcher and am able to present information in a well-organized and logical manner.

Follow Us:
LinkedinTwitter
Scroll to Top