ESP8266 - SCD40 CO2 Sensor
This tutorial instructs you how to use ESP8266 to measure the CO2 level of a room with the Sensirion SCD40 sensor. In detail, we will learn:
- How to connect ESP8266 NodeMCU to the SCD40 CO2 sensor module through I2C
- How to program ESP8266 to read the CO2 value in ppm and show if the air is good or stale
- How to get the temperature and humidity from the same SCD40 module
We suggest:
- Utilizing the MQ2 gas sensor if you want to detect smoke or gas leaks instead of CO2.
- Utilizing the DHT11 sensor if you only need temperature and humidity at a low cost.

Hardware Preparation
Or you can buy the following kits:
| 1 | × | DIYables Sensor Kit (18 sensors/displays) |
Additionally, some of these links are for products from our own brand, DIYables .
Overview of SCD40 CO2 Sensor
Many cheap "air quality" sensors only guess the CO2 level (they give an "eCO2" value). The SCD40 from Sensirion really measures CO2. It uses photoacoustic NDIR sensing: a tiny infrared light pulses inside the sensor chamber, CO2 molecules absorb some of that light and create a very small pressure "sound", and a built-in microphone measures it. More CO2 means a stronger signal. The module also has a temperature and humidity sensor inside, which it uses to correct the CO2 value.
| SCD40 | ||
|---|---|---|
| Supply voltage | 2.4V to 5.5V | |
| Interface | I2C, address 0x62 | |
| CO2 output range | 0 to 40,000 ppm | |
| CO2 accuracy | ±(50 ppm + 5% of reading), from 400 to 2,000 ppm | |
| Reading rate | one new value every 5 seconds (low-power mode | every 30 seconds) |
| Temperature accuracy | ±0.8°C (15°C to 35°C) | |
| Humidity accuracy | ±6 %RH (15°C to 35°C, 20 to 65 %RH) | |
| Average current | about 15 mA at 3.3V |
The SCD40 CO2 Sensor Pinout

The SCD40 module has four pins:
- VCC pin: must be connected to 3.3V of the ESP8266 (the module accepts 2.4V to 5.5V)
- GND pin: must be connected to GND (0V)
- SCL pin: the I2C clock line, must be connected to the SCL pin of the ESP8266
- SDA pin: the I2C data line, must be connected to the SDA pin of the ESP8266
Most SCD40 breakout modules already have pull-up resistors on SCL and SDA, so no extra resistor is needed.
※ NOTE THAT:
The order of the pins is not the same on every module. Some boards print VIN instead of VCC. Always look at the labels on your own module before wiring.
What Does the CO2 Value Mean?
CO2 is measured in ppm (parts per million). Fresh outdoor air is around 400 ppm. In a closed room, every person breathes out CO2, so the number climbs.
| CO2 level | Air quality | What to do |
|---|---|---|
| around 400 ppm | Outdoor air | nothing |
| 400 - 1000 ppm | Good indoor air | nothing |
| 1000 - 2000 ppm | Stuffy | open a window |
| above 2000 ppm | Poor | ventilate now, headache and drowsiness are possible |
Calibration and Warm-up
Automatic self-calibration (ASC) is ON by default. It assumes the sensor sees fresh, outdoor-level air (about 400 ppm) at least once a week, ideally for an hour or more. So place the sensor where fresh air reaches it from time to time, for example near a window you open every day. Also, the first few readings after power-up can be less accurate. This is normal.
Wiring Diagram
The ESP8266 is a 3.3V board, so power the SCD40 from the 3V3 pin. Connect the I2C lines to the default I2C pins of the NodeMCU: D2 (GPIO4) is SDA and D1 (GPIO5) is SCL.

This image is created using Fritzing. Click to enlarge image
See more in ESP8266's pinout and how to supply power to the ESP8266 and other components.
| SCD40 Module | ESP8266 NodeMCU |
|---|---|
| VCC | 3.3V |
| GND | GND |
| SDA | D2 (GPIO4) |
| SCL | D1 (GPIO5) |
How To Program For SCD40 CO2 Sensor
- The first step is to include the libraries:
- Create the sensor object:
- Start the I2C bus on the default ESP8266 pins and tell the library where the sensor is:
- Make a clean start, then begin periodic measurement (one reading every 5 seconds):
- In loop(), check if a new reading is ready, then read it:
Every function returns an error code. If it is not 0, errorToString() turns it into a readable message, as you will see in the full code.
ESP8266 Code for SCD40 - Read CO2
This code prints only the CO2 value and a short word about the air quality: Good, Moderate or Poor.
Detailed Instructions
To get started with ESP8266 on Arduino IDE, follow these steps:
- Check out the how to setup environment for ESP8266 on Arduino IDE tutorial if this is your first time using ESP8266.
- Wire the components as shown in the diagram.
- Connect the ESP8266 board to your computer using a USB cable.
- Open Arduino IDE on your computer.
- Choose the correct ESP8266 board, such as (e.g. NodeMCU 1.0 (ESP-12E Module)), and its respective COM port.
- Click to the Libraries icon on the left bar of the Arduino IDE.
- Search for "SCD4x", and then locate the Sensirion I2C SCD4x library by Sensirion.
- Press the Install button. When you are asked to install the dependency Sensirion Core, click Install All.
- Search for Sensirion I2C SCD4x created by Sensirion and click the Install button.
- Copy the code above and open it with the Arduino IDE.
- Click the Upload button in the Arduino IDE to compile and upload the code to the ESP8266.
- Open the Serial Monitor and wait about 5 seconds for the first value.
- Breathe gently toward the sensor, or close the door of a small room, and watch the CO2 value rise.
※ NOTE THAT:
If you see an error message instead of numbers, check that SDA goes to D2 and SCL goes to D1. Swapping these two wires is the most common mistake.
Reading Temperature and Humidity from the SCD40
The SCD40 gives three values in every reading: CO2, temperature and humidity. In the code above, readMeasurement() already fills the temperature and humidity variables, we just did not print them. The code below prints all three values. Note that the sensor sits on a warm board, so its temperature can be a little higher than the real room temperature.
Upload it in the same way and open the Serial Monitor:
Video Tutorial
Additional Knowledge
Let's compare the SCD40 with the MQ2 gas sensor used in the ESP8266 - Gas Sensor tutorial.
| SCD40 | MQ2 | |
|---|---|---|
| What it measures | real CO2 in ppm | a mix of gases (LPG, smoke, methane...) |
| Output | digital I2C value | analog voltage + digital threshold |
| Unit | ppm | no unit (raw value) |
| Extra data | temperature and humidity | none |
| Warm-up | a few readings | several minutes (24 - 48 hours when new) |
| Best for | room ventilation, classrooms, offices | gas leak and smoke alarms |
It is evident that the SCD40 is the right choice when you need a true CO2 number to know when to open a window, while the MQ2 is better for detecting dangerous gas or smoke.