Arduino + CO2 sensor MG811

Hi all, i wired a co2 sensor to an arduino board following this wiring
http://translate.google.com/translate?prev=_t&hl=en&ie=UTF-8&u=http%3A%2F%2Flusorobotica.com%2Findex.php%2Ftopic%2C111.0.html&sl=pt&tl=en&history_state0=

I have a doubt: is my map function (posted below) correct? I mean, following the specs give on its datasheet (CO2 Sensor) we should have an output of 30-50 mv (which is what i get) corresponding to 350 - 10000 ppm. Is my interpretation correct? Or should i change the way i'm reading values to get the correct ones? Thanks in advance

#define R 11 //led RED
#define L 12 //led YELLOW 1
#define G 13 //led GREEN
#define K 10 //led YELLOW 2
#define PIN 0 //analog PIN wired to co2 sensor
#define SOGLIA 1000 // 1000ppm OK value

unsigned int lettura = 0; //actual read value
unsigned int letturaOld = 0; //old read value
unsigned long time;

void reading(){ //led blinking while reading
 digitalWrite(R, LOW);
 digitalWrite(K, LOW);
 digitalWrite(G, LOW);
 int cont = 0;
 while (cont < 15){
   digitalWrite(L, HIGH);
   delay(500);
   digitalWrite(L, LOW);
   delay(500);
   cont++;
 } 
}

void victory(){ //led blinking when SOGLIA read
 digitalWrite(R, LOW);
 digitalWrite(G, HIGH);
 int cont = 0;
 while (cont < 15){
   digitalWrite(L, HIGH);
   digitalWrite(K, LOW);
   delay(500);
   digitalWrite(L, LOW);
   digitalWrite(K, HIGH);
   delay(500);
   cont++;
 } 
}

void rightWay(){ //led blinking when lettura < letturaOld
 digitalWrite(R, LOW);
 digitalWrite(K, LOW);
 digitalWrite(G, HIGH);
 int cont = 0;
 while (cont < 15){
   digitalWrite(L, HIGH);
   delay(500);
   digitalWrite(L, LOW);
   delay(500);
   cont++;
 } 
}

void wrongWay(){ //led blinking when lettura > letturaOld
 digitalWrite(R, HIGH);
 digitalWrite(K, LOW);
 digitalWrite(G, LOW);
 int cont = 0;
 while (cont < 15){
   digitalWrite(L, HIGH);
   delay(500);
   digitalWrite(L, LOW);
   delay(500);
   cont++;
 } 
}

void setup(){
  pinMode(PIN, INPUT);
  pinMode(R, OUTPUT);
  pinMode(L, OUTPUT);
  pinMode(G, OUTPUT);
  pinMode(K, OUTPUT);
  Serial.begin(9600);
}

void loop(){
  time = millis();
  if ( time <= 300000) {  //5 minutes heating time
    digitalWrite(R, HIGH);
    digitalWrite(L, HIGH);
    digitalWrite(K, HIGH);
    digitalWrite(G, HIGH);
    letturaOld = analogRead(PIN); //keeps on reading
    letturaOld = map(letturaOld,0,1023,350,10000);
    Serial.print(time/1000);
    Serial.println(" seconds elapsed. Heating in progress...");
    delay(10000);
  }
  else if ( time > 300000 && time < 305000 ) { // leds off
   digitalWrite(R, LOW);
   digitalWrite(L, LOW);
   digitalWrite(K, LOW);
   digitalWrite(G, LOW);
  }
  else{
    //blinking YELLOW led while reading
    reading();
    delay(1500);
    lettura = analogRead(PIN);
    lettura = map(lettura,0,1023,350,10000);
    Serial.print("Vecchia lettura: "); //old reading
    Serial.print(letturaOld);
    Serial.print(" | Nuova lettura: "); //new reading
    Serial.println(lettura);
    if ( lettura < SOGLIA ){
      victory(); //we're done! ding ding ding!
      delay(1500);
    }
    else{
      if (lettura < letturaOld) 
        rightWay();
      else  
        wrongWay();
    }
    letturaOld = lettura;
    lettura = 0;
    delay(1500);
  }
}

hi!

arduino's analog input pins have a resistance of several 100MOhm...
that is a factor of 1000 too low according to that datasheet...

the range 30mV to 50mV allows at "analogReference(INTERNAL);" (= appr. 1mV) a resolution of appr. 518ppmCO2/LSB...

both suggests that u use an amplifier in order to raise the input resistance and the sensitvity...
maybe a MAX9939 or a TLV4120 or a CS3302 is a good choice?

bye
arne

i don't think i understood what you said about the resolution of 500ppm (bit of an electronic noob here, just a developer :P)

another thing: if i'm using the amplifier, i'm just getting more accurate values right? i'm not looking for the precise ppm concentration, but just trying to build a device to regulate the co2 release of a machine in a "not so accurate but still, more or less, good" way :slight_smile:

i mean:
if u read 31mV on ur analog input pin,
it could also be 32mV...
so u have an error of up to +500ppmCO2...

u have just 19 different values that u can measure,
even if u use "analogReference(INTERNAL);":

the input resistance might be not so important... i m not sure :wink:

ohoh :o
i took a closer look at the datasheet
and found that the sensor has an exponential relationship between CO2 concentration and output voltage...

-arne

ok, thanks :smiley: got it :smiley: another quick question: what's its preheating time? cannot find it in any datasheet...

i found one that looked similar, and it needed a full day to reach a proper operation state... u could test it with fresh air...

i m not quite sure now: does 50mV mean 10000ppm? or 350ppm? :-?

-arne

it depends on its datasheet. the sensor from futurlec does some kind of resistance, so full voltage means no resistance --> minimum ppm values (350) and going near 0 mV means a lot of resistance --> maximum ppm values...
some other sensors act the other way (less voltage, less ppms, more voltage more ppms)... i see there's no standard here, except for the long pre heating time (no sensors go under 24 hours of preheating, some needs 7 days to work properly...)

smau (from my boss account)

I'm working on the same sensor and just getting started so I have a few questions if anybody's game. I'm using the MG811. Does the Arduino provide enough power for this? It calls for 6v +- .1v, that's just over the 5.5v available. Also, it likes to see 200mV, is there enough amperage? Lastly, how do I equate from the analogRead value to mV for my measurement? I can't figure that one out. :-[

I have been working on setting up my MG811 for a few days. So far pretty good. Yes, you do need 6V to run the heater in the Co2 sensor, the arduino will not supply this so you must get the sensor it's own voltage regulator. I have the circuit set up and it works perfect. I just need to code and calibrate. Here soon in the next few days I'm going to set up a page on wiki.bildr.org. I'll come back and post a link when it's finished.

it seems that only 5 different values could be read without the amplifier cause MG811's output is 30-50mv (the resolution of Arduino analog input is 5mv approximately).

Follows a wiring schematic which may be useful.

finally, looking forward to Nik G's page. :slight_smile:

smau the code is correct , because my result is 5000 but, what means tje result¿?¿