Trying to average data from a MQ135 Sensor

I am trying to get an average from a MQ135 sensor. This is because the readings tend to bounce around quite a bit.

I tried adapting the code in this thread, as seen below:

#include <MQ135.h>

#define PIN_MQ135 A2

MQ135 mq135_sensor(PIN_MQ135);

float temperature = 21.0; // Assume current temperature. Recommended to measure with DHT22
float humidity = 25.0; // Assume current humidity. Recommended to measure with DHT22

float Min;
float Max;
float Analog;
float Sum;
float Average;
int sampleSize = 1000;

void setup() {
  Serial.begin(9600);
}

void loop() {
  Min = 30000;        //Initilize/reset to limit
  Max = 0;        //Initilize/reset to limit
  Sum = 0;        //Initialize/reset
  
  float ppm = mq135_sensor.getPPM();
  float correctedPPM = mq135_sensor.getCorrectedPPM(temperature, humidity);

  for (int i = 0; i < sampleSize; i++)
  {
    Analog = correctedPPM;

    Sum = Sum + Analog;   //Sum for averaging

    if (Analog < Min)
      Min = Analog;

    if (Analog > Max)
      Max = Analog;
  }

  Average = (Sum / sampleSize);

  Serial.print("PPM: ");
  Serial.print(ppm);
  Serial.print("\t CorrectedPPM: ");
  Serial.print(correctedPPM);
  Serial.print("\t Min: ");
  Serial.print(Min);
  Serial.print("\t Max: ");
  Serial.print(Max);
  Serial.print("\t Average PPM: ");
  Serial.print(Average);
  Serial.println("ppm");

  delay(1000);
}

The problem is that it isn't working. If I look at the output, I get this:


Which clearly isn't right. There is no way, with that much variation between the sample sets, that the sample sets are that rock solid, with Min, Max, and Average being so close to each other.

So, back to the subject, how can I average the data coming from my MQ135?

Did you "burn in" the MQ135 for at least 48 hours, as the data sheet suggests?

If not, that will make a huge difference in the stability of the output.

It has been "on" on my desk for a couple of days. However, that doesn't address the statistics problem. It is extremely unlikely to be rock solid within sets of 1,000 while being wildly variable between sets of 1,000.

This code "averages" just one number (whatever correctedPPM happens to be), so there will be no variation at all.

  for (int i = 0; i < sampleSize; i++)
  {
    Analog = correctedPPM;

    Sum = Sum + Analog;   //Sum for averaging

    if (Analog < Min)
      Min = Analog;

    if (Analog > Max)
      Max = Analog;
  }

Consider rearranging the code so that correctedPPM is updated within the for loop.

I think I see what I did wrong. I moved the line that collected the data from the sensor into the for loop. . . Yes, the obvious, thanks.

#include <MQ135.h>

#define PIN_MQ135 A2

MQ135 mq135_sensor(PIN_MQ135);

float temperature = 21.0; // Assume current temperature. Recommended to measure with DHT22
float humidity = 25.0; // Assume current humidity. Recommended to measure with DHT22

float Min;
float Max;
float Analog;
float Sum;
float Average;
int sampleSize = 1000;

void setup() {
  Serial.begin(9600);
}

void loop() {
  Min = 30000;        //Initilize/reset to limit
  Max = 0;        //Initilize/reset to limit
  Sum = 0;        //Initialize/reset

  float ppm;
  float correctedPPM;

  for (int i = 0; i < sampleSize; i++) {
    correctedPPM = mq135_sensor.getCorrectedPPM(temperature, humidity);
    Sum = Sum + correctedPPM;   //Sum for averaging

    if (correctedPPM < Min)
      Min = correctedPPM;

    if (correctedPPM > Max)
      Max = correctedPPM;
  }

  Average = (Sum / sampleSize);
  ppm = mq135_sensor.getPPM();  //raw reading
  Serial.print("Raw_PPM: ");
  Serial.print(ppm);
  Serial.print("\t Corrected_PPM: ");
  Serial.print(correctedPPM);
  Serial.print("\t Min: ");
  Serial.print(Min);
  Serial.print("\t Max: ");
  Serial.print(Max);
  Serial.print("\t Average_PPM: ");
  Serial.print(Average);
  Serial.println("ppm");

  delay(1000);
}

Now the output looks believable. It may not be correct, but it is a lot more likely:

Unless you have actually calibrated the "burned in" MQ-135 against a known standard, the output units are meaningless.

Those sensors are not stable enough to be quantitative, and are useful only to report that the concentration of one or more of the gases they respond to in the environment has changed.

I definitely get that sensors like this are for personal amusement value. Even if they worked well, there is still no mechanism in them to tell what they are detecting, only that they are detecting something.

You might find this application interesting, where several different types of those sensors are able to categorize different odors:

Thanks, I sent a whitelist request to IT/IS so I can take a look at the article.

Before applying an average filter, get a clean reading...
Get a stable power supply, use short wires. Add a 100nF capacitor from analog pin to ground.
Be aware that you should compare to the sensor power supply voltage (if that is not stable).
The readings should be stable within +/-10 or less...

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.