Methane Values is not coming Accurate

Hi everyone,

I have been working with MQ4 gas sensor and calculating its values in ppm using graph shown in its datasheet.

Here is the code

#include <application.h>
#include <spark_wiring_i2c.h>
#include "math.h"

// ADC121C_MQ9 I2C address is 0x50(80)
#define Addr 0x50

int raw_adc = 0;
float m = 0.738; //Slope 
float b = -2.951; //Y-Intercept 
float R0 = 3.5353; //Sensor Resistance in fresh air from previous code
void setup() {
 // Set variable
  Particle.variable("i2cdevice", "ADC121C_MQ138");

  // Initialise I2C communication as MASTER
  // Initialise serial communication, set baud rate = 9600
void loop() {  
  unsigned int data[2];

  // Start I2C transmission
  // Select data register
  // Stop I2C transmission

  // Request 2 bytes of data
  Wire.requestFrom(Addr, 2);

  // Read 2 bytes of data
  // raw_adc msb, raw_adc lsb
  if (Wire.available() == 2)
    data[0] =;
    data[1] =;

// Convert the data to 12-bits
  raw_adc = ((data[0] & 0x0F) * 256) + data[1];
  float sensor_voltage = raw_adc / 2047.0 * 5;
  float RS_gas = (5* 10.0) / sensor_voltage - 10.0;
  float ratio = RS_gas /R0;
  double ppm_log = (log10(ratio)-b)/m; //Get ppm value in linear scale according to the the ratio value  
  double ppm = pow(10, ppm_log); //Convert ppm value to log scale 
  double percentage = ppm/10000; //Convert to percentage 
  Particle.publish("Ratio : ", String(ratio));
  Particle.publish(" Methane percentage % : ", String(percentage));
  Particle.publish(" PPM : ", String(ppm));

But It’s not showing sensible values of methane.

Thanx in advance.

1 Like

Can you try including the math library?

#include "math.h"

yes…Its working thanx

But PPM values is not coming accurate.

PPM :1416.819227
Methane percentage % :0.141682
Ratio :1.351705
Methane percentage % :0.141682

What does that mean exactly?
Are the other values (but PPM) correct?
What would you expect instead?

BTW, it’s been mentioned loads of times but I’ll repeat it here:
You should limit the scope of Particle.publish() to PRIVATE unless you explicitly need the events to be visible to everybody.
Also try to wrap all your data into one single event
e.g. like this

  char evtData[128];
  snprintf(evtData, sizeof(evtData), "Ratio: %.2f / %.2f ppm / %.2f %%", ratio, ppm, percentage);
  Particle.publish("Methane", evtData, PRIVATE);