CCS811 Air Quality Sensor-DFRobot

Introduction

CCS811 Air Quality Sensor can measure the eCO2 (equivalent CO2) and TVOC (Total Volatile Organic Compounds) density. It can be widely used in many applications, such as air quality detection, air purifiers, ventilation system and so on. This CCS811 air quality sensor uses AMS's unique micro-hot plate technology. Compared to conventional gas sensors, this sensor is lower power consumption, heating faster, and smaller. Internally integrated ADCs and MCUs allow data to be collected, calculated, and returned via IIC. The CCS811 supports a concentration alarm, which is triggered when the concentration exceeds the user-set threshold.

The CCS811 air quality sensor supports multiple modes, such as detect in every second, in every 10s, in every one minute, in every 250ms and sleep mode. These modes are optimized for low power consumption during the sensor measurement, so the CCS811 is also suitable for portable applications.

warning_yellow.png NOTE: The chip has stretched the clock in IIC. So, it is not compatible with some controllers, such as Raspberry Pi.

The following table shows the effects of carbon dioxide and TVOC on the human body.

Carbon Dioxide (PPM) Effect on Human TVOC Concentration (PPB) Effect on Human
<500 Normal <50 Normal
500-1000 A little uncomfortable 50-750 Anxious,uncomfortable
1000-2500 Tired 750-6000 depressive, headache
2500-5000 Unhealthy >6000 headache and other nerve problems

Features

Specification

SEN0339SIZE

Board Overview

SEN0339SVG

Num Label Description
1 VCC +
2 GND -
3 SCL IIC clock line
4 SDA IIC data line
5 INT Interrupt pin: interrupt in low level
6 WAKE Switch pin: awake in low level / sleep in high level
7 RST Reset pin: reset in low level

Tutorial

The product warm-up time is short, accurate readings can be made quickly once powered up. The read time can be shorten by setting the environmental baseline (the baseline acquisition and setup method is explained below; for more details about baseline, go to the end of the wikipage to find the related document).

warning_yellow.png NOTE: Please run the sensor for 48hours when using it for the first time.

Requirements

Connection Diagram

SEN0339CONNECT

Sample Code

1.Get Baseline

Why should we get the baseline? Because once get it, we can show the air quality quickly after the sensor warm-up by inputting the baseline. Otherwise, it will cost a long time to read correctly when startup in polluted air.

During the first week of running the sensor, it is recommended to save a new baseline every 24 hours. After 1 week of operation, it can be saved every 1-28 days

warning_yellow.png NOTE:

  • Please place it in a fresh air environment (20 minutes or more) to obtain the baseline.
  • Different sensors, different measurement cycles have different baselines.
/*!
 * @file getBaseLine.ino
 * @brief Put the module in clear air and work a few minutes, wait for baseline doing not change 
 * @n Experiment phenomenon: get
 *
 * @copyright    Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @licence     The MIT License (MIT)
 * @author [LuoYufeng](yufeng.luo@dfrobot.com)
 * @version  V0.1
 * @date  2019-07-19
 * @get from https://www.dfrobot.com
 * @url https://github.com/DFRobot/DFRobot_CCS811
 */
#include "DFRobot_CCS811.h"


/*
 * IIC address default 0x5A, the address becomes 0x5B if the ADDR_SEL is soldered.
 */
//DFRobot_CCS811 CCS811(&Wire, /*IIC_ADDRESS=*/0x5A);
DFRobot_CCS811 CCS811;

void setup(void)
{
    Serial.begin(115200);
    /*Wait for the chip to be initialized completely, and then exit*/
    while(CCS811.begin() != 0){
        Serial.println("failed to init chip, please check if the chip connection is fine");
        delay(1000);
    }
}
void loop() {
    if(CCS811.checkDataReady() == true){
        /*!
         * @brief Set baseline
         * @return baseline in clear air
         */
        Serial.println(CCS811.readBaseLine(), HEX);

    } else {
        Serial.println("Data is not ready!");
    }
    //delay cannot be less than measurement cycle
    delay(1000);
}

Expected Results

After a while, the baseline reaches to a stable value.

Result1

2.Get Data

Input the baseline value to the function sensor.writeBaseLine();If you don't want to set the baseline, please disable this function in the sample program. The sensor will automatically calibrate the baseline, but it would be a pretty long process. after the function uploaded to UNO, open the serial port monitor to check the carbide dioxide concentration and TVOC concentration.

/*!
 * @file readData.ino
 * @brief Read the concentration of carbon dioxide and TVOC
 * @n Experiment phenomenon: read data every 0.5s, and print it out on serial port. 
 *
 * @copyright    Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @licence     The MIT License (MIT)
 * @author [LuoYufeng](yufeng.luo@dfrobot.com)
 * @version  V0.1
 * @date  2019-07-19
 * @get from https://www.dfrobot.com
 * @url https://github.com/DFRobot/DFRobot_CCS811
 */
#include "DFRobot_CCS811.h"

/*
 * IIC address default 0x5A, the address becomes 0x5B if the ADDR_SEL is soldered.
 */
//DFRobot_CCS811 CCS811(&Wire, /*IIC_ADDRESS=*/0x5A);
DFRobot_CCS811 CCS811;

void setup(void)
{
    Serial.begin(115200);
    /*Wait for the chip to be initialized completely, and then exit*/
    while(CCS811.begin() != 0){
        Serial.println("failed to init chip, please check if the chip connection is fine");
        delay(1000);
    }
}
void loop() {
    if(CCS811.checkDataReady() == true){
        Serial.print("CO2: ");
        Serial.print(CCS811.getCO2PPM());
        Serial.print("ppm, TVOC: ");
        Serial.print(CCS811.getTVOCPPB());
        Serial.println("ppb");

    } else {
        Serial.println("Data is not ready!");
    }
    /*!
     * @brief Set baseline
     * @param get from getBaseline.ino
     */
    CCS811.writeBaseLine(0x447B);
    //delay cannot be less than measurement cycle
    delay(1000);
}

Expected Results

Result2

3.Concentration Alarm

Input the baseline value to the function sensor.writeBaseLine(); Upload it to UNO, when the CO2 concentration moves from the current range (low, medium, high) to another range (more than 50 ppm), an interruption is generated and the current CO2 value will be printed.

NOTE: This example requires the INT pin of the sensor to be connected to the corresponding interrupt pin on the main board (in the sample, D2 of UNO is selected).

AVR Series Interrupt Pin and Interrupt Number

328 Mainboards: Uno, Nano, Mini... Mega2560 32u4 Mainboards: Leonardo...
Interrupt Pin D2, D3 D2, D3, D21, D20, D19, D18 D3, D2, D0, D1, D7
Interrupt Number 0, 1 0, 1, 2, 3, 4, 5 0, 1, 2, 3 ,4
/*!
 * @file setInterrupt.ino
 * @brief Set interrupt parameter, when CO2 concentration range changes, get an interrupt
 * @n Experiment phenomenon: read data every 1s, and print it out on serial port.
 *
 * @copyright    Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @licence     The MIT License (MIT)
 * @author [LuoYufeng](yufeng.luo@dfrobot.com)
 * @version  V1.0
 * @date  2019-07-13
 * @get from https://www.dfrobot.com
 * @url https://github.com/DFRobot/DFRobot_Sensor
 */
#include "DFRobot_CCS811.h"

volatile  int8_t GPIO1TRIG = 0;

/*
 * IIC address default 0x5A, the address becomes 0x5B if the ADDR_SEL is soldered.
 */
//DFRobot_CCS811 CCS811(&Wire, /*IIC_ADDRESS=*/0x5A);
DFRobot_CCS811 CCS811;

void setup(void)
{
    Serial.begin(115200);
    /*wait for the chip to be initialized completely, and then exit*/
    while(CCS811.begin() != 0){
        Serial.println("failed to init chip, please check if the chip connection is fine");
        delay(1000);
    }
    attachInterrupt(0, interrupt, RISING);
    /**
     * @brief Measurement parameter configuration 
     * @param mode:in typedef enum{
     *              eClosed,      //Idle (Measurements are disabled in this mode)
     *              eCycle_1s,    //Constant power mode, IAQ measurement every second
     *              eCycle_10s,   //Pulse heating mode IAQ measurement every 10 seconds
     *              eCycle_60s,   //Low power pulse heating mode IAQ measurement every 60 seconds
     *              eCycle_250ms  //Constant power mode, sensor measurement every 250ms 1xx: Reserved modes (For future use)
     *          }eCycle_t;
     * @param thresh:0 for Interrupt mode operates normally; 1 for interrupt mode only asserts the nINT signal (driven low) if the new
     * @param interrupt:0 for Interrupt generation is disabled; 1 for the nINT signal is asserted (driven low) when a new sample is ready in
     */
    CCS811.setMeasurementMode(CCS811.eCycle_250ms, 1, 1);
    /**
     * @brief Set interrupt thresholds 
     * @param lowToMed: interrupt triggered value in range low to middle 
     * @param medToHigh: interrupt triggered value in range middle to high 
     */
    CCS811.setThresholds(1500,2500);
}
void loop() {
    if(GPIO1TRIG == 1){
        Serial.println("CO2 range has changed");
        Serial.print("CO2: ");
        Serial.print(CCS811.getCO2PPM());
        Serial.print("ppm, TVOC: ");
        Serial.print(CCS811.getTVOCPPB());
        Serial.println("ppb");
        delay(1000);
    }
    GPIO1TRIG = 0;
    Serial.print("CO2: ");
    Serial.print(CCS811.getCO2PPM());
    Serial.print("ppm, TVOC: ");
    Serial.print(CCS811.getTVOCPPB());
    Serial.println("ppb");
    CCS811.writeBaseLine(0x447B);
    delay(1000);
}


void interrupt(){
  GPIO1TRIG = 1;
}

Expected Results

Result3

FAQ

For any questions, advice or cool ideas to share, please visit the DFRobot Forum.

More Documents