# analog fluctuation of a CO2 sensor

hi all

recently i’m building a device that monitor CO2 concentration in my room

in this device i use a MG811 module as the CO2 sensor as shown below

and i wrote some code to get the analog voltage from the sensor

the voltage displayed in LCD was very unstable

i can’t find obvious change while i exhale the sensor

initially i believed it resulted from unstable output of the sensor

but when i tried using a Fluke multimeter to test

the reading on multimeter was very stable

and the voltage changed as i exhale it

i had a wrong wiring or codes?

plz help

``````#include <LiquidCrystal_I2C.h>  //quote the library of IIC LCD

LiquidCrystal_I2C L(0x27,2,1,0,4,5,6,7,3,POSITIVE);  //set the LCD address to 0x27 for a 16x2 display

void setup()
{
//Serial.begin(9600);  //open communication port
pinMode(13,OUTPUT);
digitalWrite(13,LOW);  //close the LED connected to pin13

//pinMode(12,OUTPUT);
//digitalWrite(12,HIGH);
L.begin(16,2);  //initialize LCD as a 16x2 sheet
}

float Vin;  // analog voltage from sensor
float Vex; // exponent value of Vin

float MGR(int IN)
{
pinMode(IN,INPUT);
int i;
int times=1;
float x=0;
for(i=1;i<=times;i++)
{
delay(10);
}
x=x/times;  //sum the voltage measured for ten times and divide it by ten
return x;
}
// the function that calculate the average voltage read in pin IN
// take several samples and get the average
// the interval of every sampling is 10ms

float PPM(float Vin)
{
float A=10000;
float B=5;
float x=A*pow(B,Vin);
return x;
}
// build a function that transfer input voltage to CO2 concentration
// the equation is PPM=A*B^Vin
// A and B are constant coefficients to be determined by calibration

void loop()
{
Vin=MGR(14);          // get analog signal from A0 pin
Vin=Vin*5/1023;       // transfer the voltage from digital value to real value
Vex=PPM(Vin);         // calculate CO2 concentration
//Serial.println(Vin,3);
//Serial.print(" V    ");
//Serial.print(Vex,0);
//Serial.println(" ppm");

L.setCursor(0,0);
L.print(Vin,3);   //print analog signal on first row of LCD
L.setCursor(0,1);
L.print(Vex,0);  //print CO2 concentration on second row of LCD
delay(1000);
}
``````

MG811_CO2_Sensor.ino (1.63 KB)

How to use this forum
It will tell you what information to supply.
See image guide it will tell you how to post an image.

Please show ALL your code using code tags so we can compile it ourselves.

That schematic! Not very complete is it. How does the LCD get data? Telepathy?

Try increasing this value`int times=1;`to perhaps 20?

have you ever used the MG811 sensor?

i'm curious whether the analog output of MG811 is essentially slightly unstable

or my Arduino get a wrong signal

if the signal is valid but slightly unstable

taking many samplings and calculating the average value may solve this problem

Making the code change I suggested will take 10 samples and average them. Your multimeter is in effect also doing this. I have never used this sensor, but I have used other types of noisy analog sensor. I normally use a "first-order filter" technique in my code to smooth the reading.

I have no idea what "first order filter" method is

So I just simply average the samples.

I took 1 sample voltage per 1ms

I sum 1000 samples and divided it by 1000

The output improved significantly.

The fluctuation reduced from over 100mV to just several mV

Despite it didn't work better than multimeter(below 1mV of fluctuation)

but I believe it's practical enough

The next dilemma is how I calibrate the sensor

I have no idea what "first order filter" method is

It is not a method it is a classification of a filter. It defines how quickly the filter rolls off, that is how fast the output drops as the frequency increases. A first order filter drops by 3dB per octave ( an octave is a doubling in frequency ).

The next dilemma is how I calibrate the sensor

Unless you have access to a known concentration of the gas, you don't.

A first order filter drops by 3dB per octave ( an octave is a doubling in frequency ).

Oh. Interesting. It's not what I meant, or at least what thought I meant!

By "first order filter" I meant a filter who's output tracks a "moving average" of it's input signal. But it does not track/estimate the rate of change of the signal, that would be what I would call a second order filter. For example if you tried to track the position of a vehicle moving along a long straight road at constant speed, a first order filter would always lag behind the actual position, whereas a second order filter would give a much more accurate estimate. Of course, if the vehicle was accelerating, you would need a third order filter!

Or are we talking about the same thing but I didn't realise the implications in terms of frequency response?

Or are we talking about the same thing

No.
Never heard it called that before. That sounds like what I would call a liner predictive filter.