How can I convert AnalogRead to something useful?

Hi,

I am using an MQ-7 CO sensor, and I have wired it as recommended in
http://www.parallax.com/Portals/0/Downloads/docs/prod/sens/MQ-7.pdf

I am using an RL of 20k ohm, and having implemented the variable voltage for the heater using PWM, I am getting readings of sorts from the analog read (typically around 950).

How can I go about converting this into ppm, as per the datasheet? I can't figure out what it is expecting me to do.

Regards,

No experience myself but a little google resulted in:

The datasheet is not the most clear one I've seen. This is what I understand:

  • The MQ7 is not easiest sensor
  • it is temperature and humdity sensitive (but in a first experiment this may be ignored)
  • you need to calibrate it before it can be used.
  • the reference is 100 PPM (but it uses a 10K for RL)
  • you should read a value at the end of the 1.4Volt modus when it peaks. (point b page 3)

That all said I come to something like:

The formula Rs\RL = (Vc-VRL) / VRL can be rewritten to Rs = RL * (Vc-VRL) / VRL
Vc = 5 Volts (I assume)

bringing this into the formula:

float Vrl = 5.0 * analogRead(A1) / 1023;
float Rs = 20K * ( 5.0 - Vrl) / Vrl;

So now you have a formula to make the reference measurement Ro.

If you make a measurement Rs then you can calculate the ratio Rs/Ro which can be looked up the diagram in the datasheet. To do this automagically you need to create a lookup table. The Rs/R0 varies from 0.05 - 1.5. As floats cannot be used as an index for a lookup table you better multiply them with 20 giving the values 1..30. The table is filled with PPM values.

This results in code something like below. (not complete, only indicative code, no guarantees, all disclaimers apply :slight_smile:

float Ro = xxx.yyy;

void setup()
{
}

void loop()
{
  waitForTheRightMoment();  // to be elabotated.
 
  float Vrl = 5.0 * analogRead(A1) / 1023;
  float Rs = 20K * ( 5.0 - Vrl) / Vrl;
  int ratio = 20 * Rs/Ro;
  ratio = constrain(ratio, 0, 30);
  Serial.print ( "CO :");
  Serial.println(LUT[ratio]);

}

Should help you forwards
rob

-- update --

Hi everybody, I don't fully understand why Rs/Rl = (Vc-Vrl) / Vrl

Hi everybody, I don't fully understand why Rs/Rl = (Vc-Vrl) / Vrl

Hi Thermike,

Take figure 2 of the datasheet:

The resistance of the sensor Rs is the unknown value and need to be searched for. note that Rs and Rl make a voltage divider which converts Vc into Vrl.

We know that the current through Rl equals the current through Rs:

(1) Ampere(RL) == Ampere(Rs)

Ohms law states A = V/R:

So we can express the currents as:

(2) Ampere(RL) = Vrl/Rl
(3) Ampere(Rs) = (Vc-Vrl)/Rs // e.g. Vc = 5Volt and Vrl = 3Volt, the voltage over Rs = 5-3 = 2Volt

filling (2) and (3) into (1) gives:

(4) Vrl/Rl == (Vc-Vrl)/Rs

Multiply with Rs on both sides gives:

(5) Rs*Vrl/Rl == (Vc -Vrl)

Divide by Vrl on both sides gives:

(6) Rs/Rl == (Vc -Vrl)/Vrl

QED,

Hopes this helpes.

Rob

@Cronus & Thermike
if you succeeded in making a working sketch, please post your code / schematics

Based on robtillaart's approach:

// GAS SENSOR MQ-2

// This sensor can detect smoke, methane, carbon dioxide and other gases

//VARIABLES
float Ro = 10000.0; // this has to be tuned 10K Ohm
int sensorPin = 0; // select the input pin for the sensor
int ledPin = 13; // select the pin for the LED
int val = 0; // variable to store the value coming from the sensor
float Vrl = 0.0;
float Rs = 0.0;
float ratio = 0.0;

// SETUP
void setup() {
pinMode(ledPin, OUTPUT); // declare the ledPin as an OUTPUT
Serial.begin(9600); // initialize serial communication with computer
// analogReference(EXTERNAL);
}

// get CO ppm
float get_CO (float ratio){
float ppm = 0.0;
ppm = 37143 * pow (ratio, -3.178);
return ppm;
}

// LOOP
void loop() {

val = analogRead(sensorPin); // read the value from the analog sensor
Serial.println(val); // send it to the computer (as ASCII digits)
digitalWrite(ledPin, HIGH); // turn the ledPin on
delay(100); // stop the program for some time
digitalWrite(ledPin, LOW); // turn the ledPin off
delay(100); // stop the program for some time

Vrl = val * ( 5.00 / 1024.0 ); // V
Rs = 20000 * ( 5.00 - Vrl) / Vrl ; // Ohm
ratio = Rs/Ro;

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));

delay(10000);
}

With the following to mention and ask:

  1. Ro has somehow to be figured out and I can't imagine how to make the tuning
  2. Rl suggested as 20000ohms but has to be tuned as well
  3. I preferred to make a correlation here instead of LUT. I made a table with x's and y's out of the graph and correlated the results

Rs/Ro ppm
5 200
4 500
3,5 800
3 1000
2,5 2000
2,2 3000
1,9 5000
1,5 10000
then when you correlate you get y = 37143x-3,178 with a R² = 0,9948

What do you all think?

hi guys,

i use a mq135 air quality sensor and i have i problem how to convert the values.
this is the datasheet of the sensor.
http://www.cooking-hacks.com/skin/frontend/default/cooking/pdf/MQ-135.pdf
i can't understand what is the value i receive! is it Rs?is it Rs+RL?what is it?
For sensor MQ135: Rs/RL=Vc/(Vrl-1).
Could somebody help me with the code?
the code i use , is a code from the examples:

int sensorValue; 

void setup()
{
  Serial.begin(9600);      // sets the serial port to 9600
}

void loop() 
{
  sensorValue = analogRead(0);       // read analog input pin 0
  Serial.println(sensorValue, DEC);  // prints the value read
  delay(100);                        // wait 100ms for next reading
}

I also use a resistor 10Kohm and the wiring is like that: AirQualityMQ135 \ Learning \ Wiring
the value read is about 450 and reducing.

regards

anyone could help in converting the value to ppm?plssssss

In the equation

Rs/RL=Vc/(Vrl-1).

the value that you are measuring is a function of Vrl: Vrl = sensorValue * 5.0 / 1024.0. Vc is 5.0 volts, if you are connecting the sensor to a regulated power source on the Arduino. Rl is, according to the schematic, 10K.

Now, how that will help you, I don't know. The charts are all log charts, so any ppm reading will involve the log function.

i see.. i try to use the code which is posted by thermike. well i dont know exactly if its correct because i also have difficulty in interpreting the datasheet. what ive done is. every 1.4V cycle i get the value of CO and then display in LCD.im really confused

Has anyone figured this out yet? I have an MQ-2 sensor with a potentiometer attached. I have no idea how to actually detect a proper methane reading.

http://www.ebay.com.au/itm/Arduino-Shield-Smoke-Gas-Sensor-Module-MQ2-free-Cable-/280615774635?pt=LH_DefaultDomain_0&hash=item415600e9ab

Don't know if it's of any help to you, but at the refinery I worked at they had hundreds of gas detectors, mostly for safety alarming purposes. CO2, H2S, O2, etc. These were pretty expensive industrial instruments, but the typical calibration procedure was using ambient air for the 'zero' value, and purchased 'calibration gas' bottle/regulators for setting the upper end value of the scale. That is, there was no way to calibrate just using internal voltage values, or constant values, etc, as these kinds of sensors have a finite life and age over time, so accuracy is only as good as the calibration gas you use and how frequently you performed it. We did monthly or quartily depending on the gas type and area safety ratings. The calibration gas bottles were pretty expensive also, plus they had a specified shelf life that when passed their accuracy became 'invalid' and we would have to send them back for refilling even if not empty.

Okay, now the MQ-2 seems to be working fine using the following code:

int sensorValue;

void setup()
{
  Serial.begin(9600);      // sets the serial port to 9600
}

void loop() 
{
  sensorValue = analogRead(0);       // read analog input pin 0
  Serial.println(sensorValue, DEC);
  
  if (sensorValue >= 5) {
    Serial.println("Someone let one rip!");
    delay(10000);
  }
}

so i guess the sensorValue there is in analog value.correct me if im wrong.. thank you.!

vhenamae:
so i guess the sensorValue there is in analog value.correct me if im wrong.. thank you.!

Yes, It is!

 sensorValue = analogRead(0);       // read analog input pin 0

cyclegadget:

vhenamae:
so i guess the sensorValue there is in analog value.correct me if im wrong.. thank you.!

Yes, It is!

 sensorValue = analogRead(0);       // read analog input pin 0

so.. how can i convert that analogvalue to digital? thank you

What do you mean by convert it to digital?

i mean converting it to ppm values..

I don't know. I imagine the datasheet for your sensor will have that information.

i see.. thank you sir. i already have a code. but still im not that confident about the about.

vhenamae:
i see.. thank you sir. i already have a code. but still im not that confident about the about.

Why do you want to convert to PPM?