Zbotic Logo Zbotic Logo
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

  • Shop
  • About Us
  • Contact Us
  • Reseller
  • Blogs
020 69134444
1800 209 0998
[email protected]
Help Desk
Facebook Twitter Instagram Linkedin YouTube
Zbotic Logo Zbotic Logo
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

All departments
  • 3D Print Service
  • 3D Printer
  • Batteries & Chargers
  • Development Boards
  • Drone Parts
  • EBike parts
  • Sensor Modules
  • Electronic Components
  • Electronic Modules
  • IoT and Wireless
  • Mechanical Parts and Workbench Tools
  • Motors & Drivers & Pumps & Actuators
  • DIY and Robot Kits
  • Show more
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
Return to previous page
Home Sensors & Modules

SCD40 CO2 Sensor: Accurate Carbon Dioxide Measurement Guide

SCD40 CO2 Sensor: Accurate Carbon Dioxide Measurement Guide

March 11, 2026 /Posted byJayesh Jain / 0

Indoor air quality is one of the most overlooked factors in health, productivity, and cognitive function. Studies show that elevated CO2 levels — above 1000 ppm — impair decision-making by up to 21%, and levels above 2500 ppm cause significant cognitive decline. The problem is invisible: you cannot see, smell, or taste CO2 until levels become dangerous. This is where the SCD40 CO2 sensor comes in.

The Sensirion SCD40 is a miniaturised, photoacoustic carbon dioxide sensor that delivers highly accurate CO2 measurements alongside temperature and humidity readings, all via a simple I2C interface. In this comprehensive guide, we cover everything about the SCD40 — from how it works and wiring it to Arduino, to advanced calibration techniques and building a complete indoor air quality monitor.

Table of Contents

  1. Why Measure CO2 Indoors?
  2. SCD40 Overview and Specifications
  3. How Photoacoustic Sensing Works
  4. SCD40 vs Other CO2 Sensors
  5. Wiring SCD40 to Arduino / ESP32
  6. Library Installation
  7. Basic Measurement Code
  8. Sensor Calibration
  9. Building a Complete Air Quality Monitor
  10. Understanding CO2 Level Thresholds
  11. Low-Power Operation
  12. Applications and Use Cases
  13. Frequently Asked Questions

1. Why Measure CO2 Indoors?

The outdoor atmosphere contains approximately 420 ppm (parts per million) of CO2. When people are present in enclosed spaces, CO2 levels rise rapidly as we exhale carbon dioxide. A closed classroom with 30 students can reach 3000 ppm within an hour. Home offices, bedrooms, and meeting rooms all accumulate CO2 when poorly ventilated.

Elevated indoor CO2 causes:

  • Cognitive impairment: Measurable decline in focus, decision-making, and complex task performance above 1000 ppm
  • Fatigue and drowsiness: The classic “afternoon slump” in offices is often CO2-driven
  • Headaches and discomfort: Common above 2000 ppm
  • Indicator of viral risk: CO2 level is a reliable proxy for air recirculation rate — high CO2 means poor dilution of potentially virus-laden air

CO2 monitoring became especially relevant post-pandemic as a way to assess ventilation adequacy in public spaces. In industrial settings, CO2 monitoring is used to detect leaks from compressed gas systems and dry ice storage. In agriculture, CO2 enrichment of greenhouse air (up to 1500 ppm) increases crop yields — requiring accurate CO2 measurement and control.

2. SCD40 Overview and Specifications

The Sensirion SCD40 represents a generational leap in compact CO2 sensing technology. It uses Sensirion’s proprietary PASens® (Photoacoustic Sensing) technology to miniaturise what was previously a large, power-hungry NDIR (Non-Dispersive Infrared) sensor into a tiny 2.4 × 2.9 × 1.4 mm package.

Parameter Specification
CO2 Measurement Range 400 – 2000 ppm
CO2 Accuracy ±50 ppm + 5% of reading
Temperature Range -10°C to 60°C
Temperature Accuracy ±0.8°C (typ)
Humidity Range 0 – 100% RH
Humidity Accuracy ±6% RH (typ)
Interface I2C (address 0x62)
Supply Voltage 2.4V – 5.5V
Average Current (5s interval) 1.4 mA
Peak Current 175 mA
Single-shot mode avg current ~0.4 mA (1 per 5 min)
Warm-up Time Immediate (photoacoustic, no warm-up)
Dimensions 10.1 × 33.5 × 6.5 mm (breakout board)

SCD40 vs SCD41

Sensirion also makes the SCD41, which extends the CO2 range to 400–5000 ppm — making it more suitable for greenhouse CO2 enrichment, storage monitoring, and industrial environments where levels can exceed 2000 ppm. The SCD40 is ideal for indoor air quality monitoring where 2000 ppm represents the extreme upper boundary of typical conditions.

3. How Photoacoustic Sensing Works

Traditional CO2 sensors use Non-Dispersive Infrared (NDIR) technology: infrared light passes through a sample chamber, and CO2 molecules absorb specific IR wavelengths. The reduction in transmitted IR intensity is proportional to CO2 concentration. This works well but requires a light source, a long optical path, and a photodetector — making traditional NDIR sensors relatively large and expensive.

Photoacoustic NDIR (PASens)

The SCD40 uses photoacoustic sensing, a variant of NDIR. Instead of measuring transmitted light, the sensor uses a modulated infrared light source that causes CO2 molecules to periodically absorb energy and heat up, then cool, expanding and contracting. This creates pressure waves — essentially sound — at the modulation frequency. A MEMS microphone inside the sensor detects these pressure waves.

Key advantages of photoacoustic sensing:

  • No optical path length requirement — the sensor can be miniaturised to millimetre scale
  • No reference channel needed — dramatically simplifies the optical design
  • Self-calibrating for zero drift — the signal goes to zero when no CO2 is present, unlike NDIR where zero drift accumulates
  • Faster response time compared to electrochemical CO2 sensors

4. SCD40 vs Other CO2 Sensors

Sensor Technology Accuracy Range Cost
SCD40 Photoacoustic NDIR ±50 ppm 400–2000 ppm Medium-High
MH-Z19B NDIR ±50 ppm 400–5000 ppm Medium
CCS811 MOX (eCO2) ±15% (eCO2) 400–8192 ppm Low
MQ-135 Electrochemical Poor (±30%) Variable Very Low
SCD30 NDIR (dual channel) ±30 ppm 400–10000 ppm High

Important note on CCS811 and MQ-135: These sensors do not actually measure CO2 directly. The CCS811 measures total VOC (volatile organic compounds) and derives an “equivalent CO2” estimate — it is not a substitute for true CO2 measurement and does not detect CO2 from human respiration accurately. The MQ-135 is similarly a multi-gas sensor with poor CO2 selectivity. For genuine CO2 monitoring, use NDIR or photoacoustic sensors like the SCD40.

MQ-135 Air Quality Gas Detector

MQ-135 Air Quality / Gas Detector Sensor Module

A versatile multi-gas sensor for general air quality indication — complements dedicated CO2 sensors by detecting ammonia, benzene, smoke, and other gases.

View on Zbotic

5. Wiring SCD40 to Arduino / ESP32

The SCD40 operates on I2C with a fixed address of 0x62. It accepts supply voltages from 2.4V to 5.5V, making it directly compatible with both 3.3V and 5V systems.

Wiring to Arduino Uno (5V)

SCD40 Pin Arduino Uno Pin
VDD 5V
GND GND
SDA A4 (SDA)
SCL A5 (SCL)
SEL Leave floating or connect to GND (I2C mode)

Wiring to ESP32 (3.3V)

SCD40 Pin ESP32 Pin
VDD 3.3V
GND GND
SDA GPIO 21
SCL GPIO 22

Note on peak current: The SCD40 draws up to 175 mA during measurement pulses. Always power it from the main power supply, not from a microcontroller’s 3.3V regulator output (which is often limited to 50-100 mA). Add a 10 µF electrolytic + 100 nF ceramic decoupling capacitor near the SCD40’s VDD pin.

6. Library Installation

Sensirion provides an official Arduino library for the SCD40:

  1. Open Arduino IDE → Sketch → Include Library → Manage Libraries
  2. Search for Sensirion I2C SCD4x
  3. Install Sensirion I2C SCD4x by Sensirion
  4. Also install the dependency: Sensirion Core

Alternatively, for ESP32/ESP8266 using PlatformIO, add to platformio.ini:

lib_deps = 
  sensirion/Sensirion I2C SCD4x@^0.4.0

7. Basic Measurement Code

Continuous Measurement Mode

#include <Arduino.h>
#include <SensirionI2CScd4x.h>
#include <Wire.h>

SensirionI2CScd4x scd4x;

void setup() {
  Serial.begin(115200);
  Wire.begin();
  
  uint16_t error;
  char errorMessage[256];
  
  scd4x.begin(Wire);
  
  // Stop any previous measurement before starting
  error = scd4x.stopPeriodicMeasurement();
  if (error) {
    errorToString(error, errorMessage, 256);
    Serial.print("Error stopping measurement: ");
    Serial.println(errorMessage);
  }
  
  // Start periodic measurement (every 5 seconds)
  error = scd4x.startPeriodicMeasurement();
  if (error) {
    errorToString(error, errorMessage, 256);
    Serial.print("Error starting measurement: ");
    Serial.println(errorMessage);
  }
  
  Serial.println("Waiting for first measurement...");
  delay(5000); // Wait for first sample
}

void loop() {
  uint16_t error;
  char errorMessage[256];
  bool isDataReady = false;
  
  // Check if new data is available
  error = scd4x.getDataReadyFlag(isDataReady);
  if (error) {
    errorToString(error, errorMessage, 256);
    Serial.print("Error checking data ready: ");
    Serial.println(errorMessage);
    return;
  }
  
  if (!isDataReady) {
    delay(100);
    return;
  }
  
  uint16_t co2;
  float temperature, humidity;
  
  error = scd4x.readMeasurement(co2, temperature, humidity);
  if (error) {
    errorToString(error, errorMessage, 256);
    Serial.print("Error reading measurement: ");
    Serial.println(errorMessage);
    return;
  }
  
  if (co2 == 0) {
    Serial.println("Invalid sample (co2 = 0)");
    return;
  }
  
  Serial.print("CO2: "); Serial.print(co2); Serial.print(" ppmt");
  Serial.print("Temp: "); Serial.print(temperature, 1); Serial.print(" °Ct");
  Serial.print("RH: "); Serial.print(humidity, 1); Serial.println("%");
  
  delay(100);
}

8. Sensor Calibration

The SCD40 includes two calibration mechanisms that are critical for accurate long-term measurements.

Automatic Self-Calibration (ASC)

The SCD40 continuously observes its own CO2 readings and assumes that the minimum value observed over any 7-day period is fresh outdoor air at approximately 400 ppm. It automatically adjusts its calibration accordingly. ASC is enabled by default and works well when:

  • The sensor sees outdoor-level CO2 for at least 1 hour every day
  • It operates for at least 7 consecutive days

Disable ASC if the sensor is permanently in a sealed environment (controlled atmosphere research, submarine, etc.) where it never experiences outdoor air:

scd4x.setAutomaticSelfCalibration(false);

Forced Recalibration (FRC)

Forced recalibration is used when you want immediate, precise calibration to a known CO2 reference:

// Step 1: Run sensor continuously for 3+ minutes in known CO2 atmosphere
// Step 2: Stop periodic measurement
scd4x.stopPeriodicMeasurement();
delay(500);

// Step 3: Execute FRC with known CO2 concentration (e.g., 400 ppm outdoor air)
uint16_t targetCO2 = 400; // ppm
uint16_t frcCorrection;
uint16_t error = scd4x.performForcedRecalibration(targetCO2, frcCorrection);

if (frcCorrection == 0xFFFF) {
  Serial.println("FRC failed — ensure sensor ran for 3+ minutes first");
} else {
  int16_t correctionPpm = (int16_t)frcCorrection - 0x8000;
  Serial.print("FRC correction applied: ");
  Serial.print(correctionPpm);
  Serial.println(" ppm");
}

Temperature Offset

The SCD40 measures temperature internally. Heat from nearby components can bias the temperature (and consequently humidity) readings. Set a temperature offset to correct this:

// Set +4°C offset if the enclosure raises temp by 4°C
scd4x.setTemperatureOffset(4.0);

9. Building a Complete Air Quality Monitor

Here is a complete indoor air quality monitor using the SCD40 with colour-coded LED indication and OLED display:

#include <Wire.h>
#include <SensirionI2CScd4x.h>
#include <Adafruit_SSD1306.h>

SensirionI2CScd4x scd4x;
Adafruit_SSD1306 display(128, 64, &Wire, -1);

// RGB LED pins (common cathode)
const int LED_R = 9;
const int LED_G = 10;
const int LED_B = 11;

void setLED(int r, int g, int b) {
  analogWrite(LED_R, r);
  analogWrite(LED_G, g);
  analogWrite(LED_B, b);
}

void updateAirQualityIndicator(uint16_t co2) {
  if (co2 < 800) setLED(0, 255, 0);       // Green: Good
  else if (co2 < 1200) setLED(255, 200, 0); // Yellow: Moderate  
  else if (co2 < 2000) setLED(255, 80, 0);  // Orange: Poor
  else setLED(255, 0, 0);                    // Red: Very Poor
}

void setup() {
  Wire.begin();
  Serial.begin(115200);
  
  pinMode(LED_R, OUTPUT);
  pinMode(LED_G, OUTPUT);
  pinMode(LED_B, OUTPUT);
  
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);
  
  scd4x.begin(Wire);
  scd4x.stopPeriodicMeasurement();
  scd4x.startPeriodicMeasurement();
  delay(5000);
}

void loop() {
  bool dataReady = false;
  scd4x.getDataReadyFlag(dataReady);
  if (!dataReady) { delay(100); return; }
  
  uint16_t co2;
  float temp, hum;
  scd4x.readMeasurement(co2, temp, hum);
  
  // Update LED
  updateAirQualityIndicator(co2);
  
  // Update display
  display.clearDisplay();
  display.setTextSize(1);
  display.setCursor(0, 0);
  display.println("Indoor Air Quality");
  display.drawLine(0, 10, 128, 10, SSD1306_WHITE);
  
  display.setTextSize(2);
  display.setCursor(0, 14);
  display.print(co2);
  display.setTextSize(1);
  display.println(" ppm CO2");
  
  display.setTextSize(1);
  display.setCursor(0, 42);
  display.print("Temp: "); display.print(temp, 1); display.println(" C");
  display.print("RH:   "); display.print(hum, 0); display.println("%");
  
  String quality = co2 < 800 ? "GOOD" : co2 < 1200 ? "MODERATE" : co2 < 2000 ? "POOR" : "VERY POOR";
  display.setCursor(80, 42);
  display.println(quality);
  
  display.display();
  delay(100);
}

10. Understanding CO2 Level Thresholds

CO2 Level (ppm) Classification Health Impact Action
< 400 Outdoor Fresh Air None Ideal — no action needed
400–800 Excellent None detectable Well-ventilated space
800–1200 Good Minor drowsiness possible Consider increasing ventilation
1200–2000 Moderate–Poor Cognitive impairment begins Open windows, increase airflow
2000–5000 Very Poor Headaches, fatigue, loss of focus Ventilate immediately
> 5000 Dangerous OSHA workplace limit exceeded Evacuate, investigate source

11. Low-Power Operation

The SCD40 supports a single-shot measurement mode ideal for battery-powered IoT devices. Instead of continuously measuring every 5 seconds, the sensor wakes up, takes one measurement, and returns to sleep:

// Measure once then go idle (for deep-sleep IoT applications)
void takeSingleMeasurement() {
  scd4x.stopPeriodicMeasurement();
  delay(500);
  
  scd4x.measureSingleShot();
  delay(5000); // Wait for measurement
  
  uint16_t co2;
  float temp, hum;
  scd4x.readMeasurement(co2, temp, hum);
  
  // Transmit data via LoRa/MQTT/BLE
  transmitData(co2, temp, hum);
  
  // Power down ESP32 for 5 minutes
  esp_sleep_enable_timer_wakeup(5 * 60 * 1000000ULL);
  esp_deep_sleep_start();
}

12. Applications and Use Cases

School Classroom Air Quality Monitor

Install an SCD40 with a NodeMCU and a large LED display visible from the back of the classroom. Teachers can see at a glance when ventilation is needed. Studies in Denmark and elsewhere show that reducing classroom CO2 below 900 ppm improves student performance measurably.

Smart Home Ventilation Control

Integrate the SCD40 with Home Assistant or Node-RED. When CO2 exceeds 1000 ppm, automatically activate an exhaust fan or open smart ventilation dampers. The system can also integrate with air purifiers and provide occupancy estimates based on CO2 rise rate.

Greenhouse CO2 Enrichment

Use the SCD41 (extended range) to maintain optimal CO2 levels for plant growth in controlled-environment agriculture. Most crops reach peak photosynthesis between 1200–1500 ppm. The system controls a CO2 release valve to maintain the target concentration.

DHT11 Temperature and Humidity Sensor

DHT11 Digital Relative Humidity and Temperature Sensor Module

Add a DHT11 as a secondary temperature/humidity sensor for cross-validation and redundancy alongside your SCD40 CO2 monitor.

View on Zbotic

BME280 5V Temperature and Humidity Sensor

GY-BME280-5V Temperature and Humidity Sensor

Combine the BME280 with your SCD40 for a comprehensive environmental monitoring station covering CO2, temperature, humidity, and atmospheric pressure.

View on Zbotic

Frequently Asked Questions

How long does the SCD40 take to warm up before giving accurate readings?

Unlike traditional NDIR sensors that require 3-5 minute warm-up times, the SCD40 gives its first measurement within 5 seconds of starting periodic measurement mode. The photoacoustic sensing technology used by Sensirion does not require a warm-up period. However, for the auto-calibration to stabilise after initial deployment, the sensor should run continuously for at least 7 days to establish a reliable calibration baseline.

Can the SCD40 be used outdoors?

The SCD40 can operate outdoors in terms of its measurement range and temperature tolerance (-10°C to 60°C). However, the sensor itself is not weatherproof — it must be protected from direct rain, condensation, and prolonged exposure to high humidity (above 95% RH). Mount it in a weather-resistant enclosure with a Gore-Tex membrane or similar breathable waterproof cover that allows air exchange while keeping moisture away from the electronics.

Why does my SCD40 read 400 ppm even in a closed room with people?

This is the automatic self-calibration (ASC) algorithm setting a floor at 400 ppm. If the sensor has not yet completed its initial 7-day calibration period, or if it is regularly placed in fresh outdoor air (or near a window), ASC may incorrectly calibrate to 400 ppm. To check, disable ASC with setAutomaticSelfCalibration(false) and perform a forced recalibration. Also verify the I2C communication is working correctly — check the error return values from readMeasurement().

Is the SCD40 the same as the SCD30?

No. The SCD30 is a larger, older sensor using dual-channel NDIR technology with ±30 ppm accuracy and a range up to 10,000 ppm. The SCD40 uses newer photoacoustic sensing, is much smaller (2.4 × 2.9 mm chip vs much larger SCD30 module), consumes less power, but has slightly lower accuracy (±50 ppm) and a narrower range (400-2000 ppm). The SCD40 is the modern successor optimised for miniaturised IoT and consumer applications.

Does altitude affect SCD40 CO2 readings?

Yes. At higher altitudes, lower atmospheric pressure affects photoacoustic sensing performance. The SCD40 supports ambient pressure compensation — you can set the current atmospheric pressure using setAmbientPressure() (in Pa). This is especially important at altitudes above 1000 m above sea level. In India, cities like Bangalore (920 m), Shimla (2206 m), and Leh (3524 m) would benefit from altitude compensation for accurate CO2 readings. Use a BMP280 pressure sensor to measure ambient pressure and feed it to the SCD40 for automatic compensation.

Monitor Your Indoor Air Quality Today

Find CO2 sensors, Arduino boards, and all components for your air quality monitoring project at Zbotic — trusted by makers across India.

Shop Sensors & Modules

Tags: Arduino, carbon dioxide, CO2 Sensor, indoor air quality, SCD40
Share Post
  • Facebook
  • Linkedin
  • Whatsapp
Current Limiting Circuit: Prot...
blog current limiting circuit protect components from overload 596836
blog power dissipation in resistors wattage rating guide 596840
Power Dissipation in Resistors...

Related posts

Svg%3E
Read more

Encoder Module: Position and Speed Measurement with Arduino

April 1, 2026 0
A rotary encoder converts the angular position and rotation speed of a shaft into electrical signals that Arduino can count... Continue reading
Svg%3E
Read more

Infrared Obstacle Sensor: Line Follower and Object Detection

April 1, 2026 0
Infrared obstacle sensors are the building blocks of line-following robots, edge detection systems, and proximity triggers. These tiny modules emit... Continue reading
Svg%3E
Read more

Rain Sensor and Raindrop Detection Module: Arduino Guide

April 1, 2026 0
A rain sensor module detects the presence of water droplets on its surface, giving Arduino a simple signal to trigger... Continue reading
Svg%3E
Read more

LiDAR Sensor TFmini: Distance Measurement Beyond Ultrasonic

April 1, 2026 0
When ultrasonic sensors hit their limits — range too short, accuracy too coarse, outdoor sunlight causing interference — LiDAR sensors... Continue reading
Svg%3E
Read more

Pressure Sensor BMP280: Weather Station and Altitude Meter

April 1, 2026 0
The BMP280 barometric pressure sensor by Bosch measures atmospheric pressure with ±1 hPa accuracy and temperature with ±1°C precision. These... Continue reading

Add comment Cancel reply

Your email address will not be published. Required fields are marked

Facebook Twitter Instagram Pinterest Linkedin Youtube

Get the latest deals and more.

Download on Google Play Download on the App Store

Call us: 020 69134444 / 1800 209 0998

Monday - Saturday 09:30 AM - 06:00 PM
For Technical Supports Email: [email protected]
For Sales / Enquiries Email: [email protected]

  • My Account

    • Cart

    • Wishlist

    • Checkout

    • My Orders

    • Track Order

    • My Account

  • Information

    • FAQs

    • Blogs

    • Career

    • About Us

    • Contact Us

    • Payment Options

  • Policies

    • Privacy Policy

    • Terms & Conditions

    • GST Input Tax Credit

    • Shipping Return Policy

    • E-Waste Collection Points

    • Our Sitemap

© Zbotic.in is registered trademark of Moxie Supply Pvt Ltd – All Rights Reserved
Login
Use Phone Number
Use Email Address
Not a member yet? Register Now
Reset Password
Use Phone Number
Use Email Address
Register
Already a member? Login Now