Example Code for Arduino-CO2 Concentration Measurement
Last revision 2026/01/12
This tutorial is designed for you to learn how to use the infrared CO2 sensor to measure the current CO2 concentration in the air in 5 minutes.
Sample Code
/*!
* @file CO2SensorPWMInterface.ino
* @brief This example The sensors detect CO2
* @details Infrared CO2 Sensor range : 400-4980ppm
* @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
* @license The MIT License (MIT)
* @author [qsjhyy]([email protected])
* @version V2.0
* @date 2023-01-15
*/
#if defined(ESP32) || defined(ESP8266)
// D7 pin is used as interrupt pin by default, other non-conflicting pins can also be selected as external interrupt pins.
#define SENSOR_DATA_PIN (D7) // Sensor PWM interface
#define INTERRUPT_NUMBER digitalPinToInterrupt(SENSOR_DATA_PIN) // interrupt number
#elif defined(ARDUINO_SAM_ZERO)
// Pin 5 is used as interrupt pin by default, other non-conflicting pins can also be selected as external interrupt pins
#define SENSOR_DATA_PIN (5) // Sensor PWM interface
#define INTERRUPT_NUMBER digitalPinToInterrupt(SENSOR_DATA_PIN) // interrupt number
#else
/* The Correspondence Table of AVR Series Arduino Interrupt Pins And Terminal Numbers
* ---------------------------------------------------------------------------------------
* | | DigitalPin | 2 | 3 | |
* | Uno, Nano, Mini, other 328-based |--------------------------------------------|
* | | Interrupt No | 0 | 1 | |
* |-------------------------------------------------------------------------------------|
* | | Pin | 2 | 3 | 21 | 20 | 19 | 18 |
* | Mega2560 |--------------------------------------------|
* | | Interrupt No | 0 | 1 | 2 | 3 | 4 | 5 |
* |-------------------------------------------------------------------------------------|
* | | Pin | 3 | 2 | 0 | 1 | 7 | |
* | Leonardo, other 32u4-based |--------------------------------------------|
* | | Interrupt No | 0 | 1 | 2 | 3 | 4 | |
* |--------------------------------------------------------------------------------------
* ---------------------------------------------------------------------------------------------------------------------------------------------
* The Correspondence Table of micro:bit Interrupt Pins And Terminal Numbers
* ---------------------------------------------------------------------------------------------------------------------------------------------
* | micro:bit | DigitalPin |P0-P20 can be used as an external interrupt |
* | (When using as an external interrupt, |---------------------------------------------------------------------------------------------|
* |no need to set it to input mode with pinMode)|Interrupt No|Interrupt number is a pin digital value, such as P0 interrupt number 0, P1 is 1 |
* |-------------------------------------------------------------------------------------------------------------------------------------------|
*/
// Open the external interrupt 0, connect INT1/2 to the digital pin of the main control:
// UNO(2), Mega2560(2), Leonardo(3), microbit(P0).
#define SENSOR_DATA_PIN (2) // Sensor PWM interface
#define INTERRUPT_NUMBER (0) // interrupt number
#endif
// Used in interrupt, calculate pulse width variable
volatile unsigned long pwmHighStartTicks=0, pwmHighEndTicks=0;
volatile unsigned long pwmHighVal=0, pwmLowVal=0;
// interrupt flag
volatile uint8_t flag=0;
void interruptChange()
{
if (digitalRead(SENSOR_DATA_PIN)) {
pwmHighStartTicks = micros(); // store the current micros() value
if(2 == flag){
flag = 4;
if(pwmHighStartTicks > pwmHighEndTicks) {
pwmLowVal = pwmHighStartTicks - pwmHighEndTicks;
}
}else{
flag = 1;
}
} else {
pwmHighEndTicks = micros(); // store the current micros() value
if(1 == flag){
flag = 2;
if(pwmHighEndTicks > pwmHighStartTicks){
pwmHighVal = pwmHighEndTicks - pwmHighStartTicks;
}
}
}
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("beginning...");
pinMode(SENSOR_DATA_PIN, INPUT);
attachInterrupt(INTERRUPT_NUMBER, interruptChange, CHANGE);
}
void loop() {
if(flag == 4){
flag = 1;
float pwmHighVal_ms = (pwmHighVal * 1000.0) / (pwmLowVal + pwmHighVal);
if (pwmHighVal_ms < 0.01){
Serial.println("Fault");
}
else if (pwmHighVal_ms < 80.00){
Serial.println("preheating");
}
else if (pwmHighVal_ms < 998.00){
float concentration = (pwmHighVal_ms - 2) * 5;
// Print pwmHighVal_ms
Serial.print("pwmHighVal_ms:");
Serial.print(pwmHighVal_ms);
Serial.println("ms");
//Print CO2 concentration
Serial.print(concentration);
Serial.println("ppm");
}else{
Serial.println("Beyond the maximum range : 398~4980ppm");
}
Serial.println();
}
}
Result
Please wait at least 3 minutes (preheat process) until the data is stable. At this time, the sensor can display the CO2 concentration.

Was this article helpful?
