Back to Sensors & Actuators Series

Digital Air Quality Sensor: CCS811 (eCO2 & TVOC)

April 10, 2026 Wasil Zafar 9 min read

CCS811 deep dive — MOX gas sensing, eCO2/TVOC measurement, baseline calibration, Arduino code, and indoor air quality applications.

Contents

  1. Working Principle
  2. Electrical Characteristics
  3. Interfacing with MCU
  4. Calibration
  5. Code Example
  6. Real-World Applications
  7. Limitations

Working Principle

The CCS811 from ScioSense (formerly AMS) is a digital metal-oxide (MOX) gas sensor that measures equivalent CO₂ (eCO2) and Total Volatile Organic Compounds (TVOC) in indoor air. A heated metal-oxide sensing layer changes resistance when reducing gases (VOCs, CO, etc.) adsorb onto its surface. An on-chip MCU converts the resistance change into calibrated eCO2 and TVOC readings via a proprietary algorithm.

Note: The CCS811 does NOT directly measure CO₂ molecules. It measures VOCs and estimates CO₂ from the correlation between indoor VOC levels and human-exhaled CO₂. For true CO₂ measurement, use the MH-Z19B NDIR sensor.

Electrical Characteristics

ParameterValue
eCO₂ Range400–32,768 ppm
TVOC Range0–29,206 ppb
Supply Voltage1.8–3.6 V
InterfaceI2C (addr 0x5A or 0x5B)
Measurement Modes1 sec, 10 sec, 60 sec, 250 ms (raw)
Current Draw~30 mA (1 sec mode), ~0.6 mA (60 sec mode)
Warm-Up Time20 min (initial burn-in: 48 hours for accuracy)
On-Chip MCUYes (resistance → eCO2/TVOC conversion)
Baseline Save/RestoreSupported via I2C registers

Interfacing with an MCU

Connect via I2C (SDA, SCL) with pull-ups. ADDR pin selects between 0x5A (default) and 0x5B. The WAKE pin must be pulled LOW before communication and can be driven HIGH to save power between reads. nINT pin provides a data-ready interrupt.

Humidity compensation: The CCS811 accepts humidity and temperature data (from a DHT22 or BME280) via I2C to improve eCO2 accuracy. This is optional but recommended.

Calibration

  • Burn-in: Run continuously for 48 hours on first use for sensor conditioning
  • Baseline management: Read the baseline register after 20 min warm-up and save to EEPROM; restore on every boot
  • Humidity compensation: Write current temperature and humidity via ENV_DATA register for improved accuracy
  • Fresh air reference: Periodically expose to clean outdoor air (~400 ppm CO2) to reset baseline

Code Example

/*
 * CCS811 Air Quality Sensor — Arduino
 * Library: Adafruit CCS811 (install via Library Manager)
 * Wiring: VIN → 3.3V, GND → GND, SDA → A4, SCL → A5
 *         WAKE → GND (always awake)
 */
#include <Adafruit_CCS811.h>

Adafruit_CCS811 ccs;

void setup() {
    Serial.begin(9600);
    if (!ccs.begin()) {
        Serial.println("CCS811 not found!");
        while (1);
    }
    /* Wait for sensor to be ready */
    while (!ccs.available());
    Serial.println("CCS811 Ready (warm-up 20 min for accuracy)");
}

void loop() {
    if (ccs.available()) {
        if (!ccs.readData()) {
            Serial.print("eCO2: ");
            Serial.print(ccs.geteCO2());
            Serial.print(" ppm  TVOC: ");
            Serial.print(ccs.getTVOC());
            Serial.println(" ppb");
        }
    }
    delay(1000);
}

Real-World Applications

Indoor Air Quality Monitoring & Smart Ventilation

CCS811 is used in consumer air quality monitors (like the AirVisual), HVAC demand-controlled ventilation systems, smart home CO2 alerts, and classroom/office air quality dashboards. Elevated CO2 (>1000 ppm) correlates with reduced cognitive performance — the sensor triggers ventilation before occupants feel drowsy.

IAQHVACSmart HomeCO2 Monitor

Limitations

  • Not a true CO2 sensor: Estimates CO2 from VOCs; inaccurate in environments with few occupants or non-human VOC sources.
  • Long warm-up: 20-minute minimum per power-on; 48-hour initial burn-in required.
  • Drift: MOX sensors drift over time; baseline must be periodically refreshed in clean air.
  • Cross-sensitivity: Alcohol, cleaning products, and cooking fumes cause large eCO2 spikes unrelated to actual CO2.
  • End of life: The CCS811 is now discontinued; consider the ENS160 as a newer replacement.