# Calculating Rs/Ro for MQ138 Gas Sensor

Hi Guys!
Thanks in advance for your help. I am trying to use a MQ138 gas sensor to create a formaldehyde detector. In order to do this i have to find the ratio of Rs/Ro and somehow convert that into ppm. The device then corresponds different ppm-levels with different danger levels which it displays on an lcd and with an array of LEDs.

I am very confused about how to go about calculating Rs/Ro and correlating that to ppm and also the placement of different elements in my code (like where to put the Rs and Ro formulas). I know my code is pretty jumbled but i’d appreciate any help I could get.

I have attached the logarithmic graph from the data sheet which gives you the values to plug into the Rs/Ro equation I think (???). The molecular formula for Formaldehyde is HCHO.

Thanks again!

``````#include <LiquidCrystal.h>
LiquidCrystal lcd(12,11,5,4,3,2);
float Ro=10000.0;
int sensorPin = A0;  // analog pin that reports gas sensor values
int r1=9;
int y1 = 7;
int y2= 8;
int g1=1;
int g2=6;
//voltage values from gas sensor go through A0 pin to the computer
float Rs = 0.0;
float RS_RO_ratio = 0.0;
float RL=2550;
int x;
int log2point7 = 0.43136376;

void setup() {
pinMode(r1, OUTPUT); // declare the ledPin as an OUTPUT
pinMode(y1, OUTPUT);
pinMode(y2, OUTPUT);
pinMode(g1, OUTPUT);
pinMode(g2, OUTPUT);
Serial.begin(9600);      // initialize serial communication with computer at 9600
// analogReference(EXTERNAL);
lcd.print(16,2); //establishes number of columns and rows in LCD
}

// LOOP
void loop() {
float total=0;
for(int i=0; i<50; i++);
{
total =total+Rs;
float avg = total 50; //this means that there is less fluctuation in the calculation if the value is an average
float RS_RO_ratio = avg/Ro;
sensorRead = constrain(sensorRead, 5, 1000); //constrains the values read from the gas sensor/A0 to between 5 and 900
delay(1000);
int ppm = (get_CO(ratio));

//= sensorRead * ( 5.00 / 1023.0  );      // V
Rs = 20000 * ( 5.00 - sensorRead) / sensorRead ;   // Ohm
total = total + Rs;

total + =RO;
Serial.println (RO);
Serial.println (total);
delay (500);
float avg = total/50;
float RS_RO_ratio = avg/ Ro {
float ppm = pow * (10, ((-log(RS_RO_ratio))/log2point7)+2
Serial.prinln(ppm);
return ppm;
}

//On Serial Monitor
Serial.print ( "Vrl / Rs / ratio:");
Serial.print (Vrl);
Serial.print(" ");
Serial.print (Rs);
Serial.print(" ");
Serial.println(ratio);
Serial.print ( "CO ppm :");
Serial.println(get_CO(ratio));

//On LCD
lcd.setCursor(0,1);
lcd.print(get_CO(ratio));
lcd.print("   ");
delay(100);
//Warnings
lcd.print(16, 2);
if (ppm >= 2 );
{lcd.setCursor (1,1);
lcd.print("15m-DANGER");
digitalWrite (g1, HIGH);
digitalWrite (g2, HIGH);
digitalWrite (y1, HIGH);
digitalWrite (y2, HIGH);
digitalWrite (r1, HIGH);
}
if(0.1 >= ppm <= 1.99)
{
if(0.1 >= ppm <= 0.5)
{
digitalWrite (g1, HIGH);
digitalWrite (g2, HIGH);
digitalWrite (y1, LOW);
digitalWrite (y2, LOW);
digitalWrite (r1, LOW);
}
else if(0.51 >= ppm <= 1.25)
{
digitalWrite (g1, HIGH);
digitalWrite (g2, HIGH);
digitalWrite (y1, HIGH);
digitalWrite (y2, LOW);
digitalWrite (r1, LOW);
}
else if(0.126 >= ppm <= 1.99)
{
digitalWrite (g1, HIGH);
digitalWrite (g2, HIGH);
digitalWrite (y1, HIGH);
digitalWrite (y2, HIGH);
digitalWrite (r1, LOW);
}

int x = (get_CO(ratio));
x = constrain(x, 0.1, 1.99);
x=map(x, 0.1, 1.99, 480, 5);
lcd.setCursor (1,1);
lcd.print(x);
lcd.setCursor (1, 5);
lcd.print( "CAUTION");
}

if(0.09 >= ppm)
{lcd.setCursor (1,1);
lcd.print("480m-SAFE  ");
digitalWrite (g1, HIGH);
digitalWrite (g2, LOW);
digitalWrite (y1, LOW);
digitalWrite (y2, LOW);
digitalWrite (r1, LOW);
}

}
``````

MQ138 Logarithmic graph.pdf (115 KB)

Ro means resistance of in 100ppm Toluene under different tem. and humidity.
sensor in 100ppm Toluene.

So, what value did you measure for Ro?

Rs means resistance of sensor
resistance in different gases

This is what you measure (indirectly, perhaps).

How are you measuring Rs?

From the chart it looks like the resistance in clean air will be about 3.8 times R0. Measure the resistance (after the necessary warm-up period) and divide by 3.8 to get R0. You will also want to measure temperature and humidity so you can correct for those errors.