Interfacing with a CO2 sensor

Hey, I have been asked to make a simple carbon dioxide monitoring system. My only issue is that I am really only a programmer and have limited knowledge about electronics. In the data sheet, they have a diagram for interfacing with a external micro controller ( Although I have an idea of what to do, I do not want to damage the expensive sensor in anyway and would feel more comfortable if someone reaffirmed me.

I have already poked around online and seem to have stumbled on some working code already:

int pin=14; unsigned long duration;

void setup() { pinMode(pin, INPUT); Serial.begin(115200); } void loop() { unsigned long ppm; // adding for clarity

duration = pulseIn(pin, HIGH); // get the raw reading ppm = duration - 177000UL; // subtract the 'zero point' ppm /= 500UL; // divide by the gain ppm += 350UL; // add the zero point back in

Serial.print(" PPM Co2: "); Serial.print(ppm,DEC); Serial.print(" Raw Sensor: "); Serial.println(duration,DEC); }

I am really hoping someone can give me a detailed explanation of what I need to do but any help is appreciated.


the co2 sensor and the arduino need to share a common ground voltage level…
how does ur power supply look like?

the PWM output varies between 0V and V+ of the CO2 sensor…
the arduino needs below 30% of its supply voltage for a digital LOW…
the arduino needs above 70% of its supply voltage for a digital HIGH…
but the arduino doesnt like voltages below 0V or above its supply voltage…
maybe u need a voltage divider if the PWM output voltage can be higher than the arduino supply voltage…?

i would use the following method to convert the PWM into the ppmCO2 value, because it doesnt depend on an accurate time (on my arduino i have an error of +0.3% IIRC… 0.3% of 1004ms (~=~3ms) corresponds to 6ppmCO2):

uint16_t pwm2ppm(uint8_t pin) {
  while (digitalRead(pin) == HIGH);
  while (digitalRead(pin) == LOW);
  uint32_t h,l;
  for (h=0; digitalRead(pin) == HIGH; h++);
  for (l=0; digitalRead(pin) == LOW; l++);
  // h+l <=> 1004msec
  // 1004*h/(h+l) <=> duty cycle D in msec
  // (D-177)/0.5 + 350 = ppmCO2
  return ((2*1004*h+1004)/(h+l)-2*177) + 350; // +1004 for proper rounding...(?)

maybe u should even disable interrupts…


btw: 1. do u know where pin 14 is? i think it is analog pin 0...

2. after a reset all analog pins r configured as inputs... so that u can be quite sure, that the sensor isnt damaged by them... but maybe u want to put a resistor (2kOhm or so) between the arduino pin and the sensor PWM output... just to be sure... :-)


Thanks for the reply. Here is a link to where I got the code from:

In the post, he seems to have gotten correct input using just two resistors and the code provided but I wanted to be sure of where exactly he put them.

according to the K22 datasheet (page 6 & 5) u dont need ur own pull-up resistor (4.7k to 5V), because the K22 already contains its own on-board...

the 10k is just for the case, that u re-conf pin #14 as output pin and give 5V on it... :-) everything clearly above 125 Ohm should be safe here, because arduino pins can take 40mA... according to the K22 datasheet there is already a 120 Ohm resistor on the K22 board... the BC847 on the K22 can take even more than 40mA...

i like my approach (without pulseIn()) still better... :-)


hmm so you are basically saying i can just connect the sensor without any resistors (unless i want to be on the safe side)?

also i think ill try the method described in the other post first because i know it has been tested and works. after i get it working ill be sure to try the method you described.


Hopefully you have gotten this interface working!

I am a representative from CO2Meter and have noticed this forum post. I’d just like to add that we have a guide written specifically for Arduino boards that will guide you through interfacing with the sensor over I2C:

Using a purely digital form of communications will generally provide a higher degree of accuacy.

Let me know if you have any further questions!

WOW very nice, a rep helping you out! Fantastic! Rare, but awesome!

Hey Andrew, Thanks for the post! I did get the CO2 sensor working via PWM. The guide you linked seems very helpful. I thought about using I2C in the beginning but I wasn't too comfortable with it.

One question I have is what do you think a average house CO2 level should be? I read in around 600-750 ppm on average. I want to make sure I did my math right and it is calibrated.

Thanks, Eric

Hi Andrew,
I just finally logged back on today and got your message… yes 600-800 ppm is where most residences sit.
If you have your space filled with green plants like a greenhouse then the co2 can go lower as it is consumed by the respirating plants.

ps good luck with that project