Device Driver for AMS CCS 811 digital gas sensor for monitoring Indoor Air Quality (IAQ) More...

Detailed Description

Device Driver for AMS CCS 811 digital gas sensor for monitoring Indoor Air Quality (IAQ)

Driver for the ams CCS811 digital gas sensor for monitoring indoor air quality.

The driver is for the usage with RIOT-OS.

<a name="toc"> Table of contents </a>

  1. Overview
    1. About the sensor
    2. Supported features
  2. Measurement Process
    1. Sensor modes
    2. Measurement results
  3. Compensation
  4. Negative Thermal Coefficient Thermistor (NTC)
  5. Interrupts
    1. Data ready interrupt
    2. Threshold interrupt
  6. Power Saving
  7. Baseline
  8. Error Handling
  9. Configuration
    1. Hardware Configurations
    2. Driver Configuration Parameters

<a name="overview"> Overview </a>    [<a href="#toc">TOC</a>]

<a name="about"> About the sensor </a>    [<a href="#toc">TOC</a>]

The CCS811 is an ultra-low power digital sensor which detects Volatile Organic Compounds (VOC) for Indoor Air Quality (IAQ) monitoring that. The sensor allows to

Note
The sensor is connected to I2C interface and uses clock stretching. The I2C implementation of the MCU has to support clock stretching to get CCS811 working.

<a name="supported"> Supported Features </a>    [<a href="#toc">TOC</a>]

Note
There are two driver module versions, the ccs811 module which provides only basic functionality and the ccs811_full module with additional functionality.

The ccs811_full module includes the ccs811 module automatically. If code size is critical, the ccs811 module can be used, otherwise using the ccs811_full module is recommended.

The driver supports the following features when modules ccs811 and ccs811_full are used.

Feature Module
read raw and converted gas sensor data (eCO2, TVOC) ccs811
poling for new sensor gas data ccs811
power saving using sleep mode with wakeup ccs811
data ready and threshold interrupt handling ccs811_full
ambient temperature calculation with NTC ccs811_full
compensate gas readings using an external sensor ccs811_full
manual baseline handling ccs811_full

<a name="measurement_process"> Measurement Process </a>    [<a href="#toc">TOC</a>]

<a name="sensor_modes"> Sensor modes </a>    [<a href="#toc">TOC</a>]

After power up, the sensor starts automatically in Idle, Low Current Mode (CCS811_MODE_IDLE). To start periodic measurements, the mode of the sensor has to be changed to any measurement mode. Measurement modes with different output data rates are available:

Mode Driver symbol Period RAW data IAQ values
Idle, Low Current Mode CCS811_MODE_IDLE - - -
Constant Power Mode CCS811_MODE_1S 1 s X X
Pulse Heating Mode CCS811_MODE_10S 10 s X X
Low Power Pulse Heating Mode CCS811_MODE_60S 60 s X X
Constant Power Mode CCS811_MODE_250MS 250 ms X -

In Constant Power Mode with measurements every 250 ms (CCS811_MODE_250MS) only raw data are available. In all other measurement modes, the Indoor Air Quality (IAQ) values are available additionally. The Constant Power Mode with measurements every 250 ms (CCS811_MODE_250MS) is only intended for systems where an external host system wants to run an algorithm with raw data.

Note
  • After setting the mode, the sensor is in conditioning period that needs up to 20 minutes, before accurate readings are generated, see the data sheet for more details.
  • During the early-live (burn-in) period, the CCS811 sensor should run for 48 hours in the selected mode of operation to ensure sensor performance is stable, see the data sheet for more details.
  • When the sensor operating mode is changed to a new mode with a lower sample rate, e.g., from Pulse Heating Mode (CCS811_MODE_10S) to Low Power Pulse Heating Mode (CCS811_MODE_60S), it should be placed in Idle, Low Current Mode (CCS811_MODE_IDLE) for at least 10 minutes before enabling the new mode. When the sensor operating mode is changed to a new mode with a higher sample rate, e.g., from Low Power Pulse Heating Mode* (CCS811_MODE_60S) to Pulse Heating Mode (CCS811_MODE_10S), there is no requirement to wait before enabling the new mode.

When default configuration parameters from ccs811_params.h are used, the CCS811_MODE_1S measurement mode is used automatically. The application can change the measurement mode either

<a name="measurement_results"> Measurement results </a>    [<a href="#toc">TOC</a>]

Once the measurement mode is set, the user task can use function ccs811_read_iaq to fetch the results. The function returns raw data as well as Indoor Air Quality (IAQ) values. If some of the results are not needed, the corresponding parameters can be set to NULL.

While raw data represents simply the current through the sensor and the voltage across the sensor with the selected current, IAQ values are the results of the processing of these raw data by the sensor. IAQ values consist of the equivalent CO2 (eCO2) with a range from 400 ppm to 8192 ppm and Total Volatile Organic Compound (TVOC) with a range from 0 ppb to 1187 ppb.

uint16_t iaq_tvoc;
uint16_t iaq_eco2;
uint16_t raw_i;
uint16_t raw_v;
...
/* get the results and do something with them */
if (ccs811_read_iaq (&sensor, &tvoc, &eco2, &raw_i, &raw_v) == CCS811_OK) {
...
}
else {
... /* error handling */
}
...

If the ccs811_read_iaq function is called and no new data are available, the function returns the results of the last valid measurement and error code CCS811_ERROR_NO_NEW_DATA.

There are two approaches to wait until new data are available:

uint16_t iaq_tvoc;
uint16_t iaq_eco2;
uint16_t raw_i;
uint16_t raw_v;
...
/* check whether new data are available, get the data and do something with them */
if (ccs811_data_ready (&sensor) == CCS811_OK &&
ccs811_read_iaq (&sensor, &tvoc, &eco2, &raw_i, &raw_v) == CCS811_OK)
{
...
}
...

When using data-ready interrupts, the default configuration parameter for the interrupt pin can be overridden by defining CCS811_PARAM_INT_PIN before ccs811_params.h is included.

<a name="compensation"> Compensation </a>    [<a href="#toc">TOC</a>]

If information about the environment like temperature and humidity are available from another sensor, they can be used by CCS811 to compensate gas readings due to temperature and humidity changes.

Note
This feature can only be used with the ccs811_full module.

Function ccs811_set_environmental_data can be used to set these environmental data. In the following example, the Sensirion SHT3x humidity and temperature sensor is used to fetch environmental data.

int16_t temperature; /* in hundredths of a degree Celsius */
int16_t humidity; /* in hundredths of a percent */
...
if (sht3x_get_results (sht3x, &temperature, &humidity))
/* set CCS811 environmental data with values fetched from SHT3x */
ccs811_set_environmental_data (ccs811, temperature, humidity);
...

<a name="ntc"> Negative Thermal Coefficient Thermistor (NTC) </a>    [<a href="#toc">TOC</a>]

CCS811 supports an external interface for connecting a negative thermal coefficient thermistor (R_NTC) to provide a cost effective and power efficient means of calculating the local ambient temperature.

Note
This feature can only be used with the ccs811_full module.

The sensor measures the voltage V_NTC across R_NTC as well as the voltage V_REF across a connected reference resistor (R_REF). Function ccs811_read_ntc can be used at any time to fetch the current resistance of R_NTC. It uses the resistance of R_REF and measured voltages V_REF and V_NTV with the following equation to determine R_NTC:

R_NTC = R_REF / V_REF * V_NTC

Using the data sheet of the NTC, the ambient temperature can be calculated. See application note AMS AN000372 for more details. For example, with Adafruit CCS811 Air Quality Sensor Breakout the ambient temperature can be determined as following:

...
#define CCS811_R_REF 100000 /* resistance of the reference resistor */
#define CCS811_R_NTC 10000 /* resistance of NTC at a reference temperature */
#define CCS811_R_NTC_TEMP 25 /* reference temperature for NTC */
#define CCS811_BCONSTANT 3380 /* B constant */
/* get NTC resistance */
uint32_t r_ntc;
ccs811_read_ntc (&sensor, CCS811_R_REF, &r_ntc);
/* calculation of temperature from application note ams AN000372 */
double ntc_temp;
ntc_temp = log((double)r_ntc / CCS811_R_NTC); /* 1 */
ntc_temp /= CCS811_BCONSTANT; /* 2 */
ntc_temp += 1.0 / (CCS811_R_NTC_TEMP + 273.15); /* 3 */
ntc_temp = 1.0 / ntc_temp; /* 4 */
ntc_temp -= 273.15; /* 5 */
....

<a name="interrupts"> Interrupts </a>    [<a href="#toc">TOC</a>]

CCS811 supports two types of interrupts that can be used to fetch data:

Note
  • Interrupts can only be used with the ccs811_full module.
  • It is not possible to use both interrupts at the same time.

<a name="data_ready_interrupt"> Data ready interrupt </a>    [<a href="#toc">TOC</a>]

At the end of each measurement cycle (every 250 ms, 1 second, 10 seconds, or 60 seconds), CCS811 can optionally trigger an interrupt. The signal nINT** is driven low as soon as new sensor values are ready to read. It will stop being driven low when sensor data are read with function ccs811_read_iaq.

The interrupt is disabled by default. It can be enabled using function ccs811_set_int_mode.

...
/* enable the data ready interrupt */
ccs811_set_int_mode (&sensor, CCS811_INT_DATA_READY);
...

<a name="threshold interrupt"> Threshold interrupt </a>    [<a href="#toc">TOC</a>]

The user task can choose that the data ready interrupt is not generated every time when new sensor values become ready but only if the eCO2 value moves from the current range (LOW, MEDIUM, or HIGH) into another range by more than a hysteresis value. Hysteresis is used to prevent multiple interrupts close to a threshold.

The interrupt is disabled by default and can be enabled with function ccs811_set_int_mode. The ranges are defined by the ccs811_set_eco2_thresholds function and its parameters low and high as following:

Name Range Value Default
LOW below the low parameter > 400 1500
MEDIUM between the low and high parameters
HIGH above the value of the high parameter < 8192 2500
...
/* set threshold parameters and enable threshold interrupt mode */
ccs811_set_eco2_thresholds (&sensor, 600, 1100, 40);
...

<a name="power saving"> Power Saving </a>    [<a href="#toc">TOC</a>]

The CCS811 offers a sleep mode with wake-up function. By using the active low nWAKE signal connected to a GPIO, power can be saved. If the nWAKE** signal is low, the CCS811 is active and can communicate over I2C. When this signal is high, the CCS811 goes into sleep mode and can't be reached via I2C. The measuring process is not affected.

The driver supports this feature when the nWAKE signal pin (ccs811_params_t::wake_pin) is configured, see the Configuration section.

Note
If the nWAKE signal pin is not used, it must be permanently pulled down. Sleep mode/wake-up feature can not be used in this case.

Additionally, CCS811 can be disabled with the ccs811_power_down function function, when no measurements are required. For that purpose, the sensor is switched to the idle, low current mode (CCS811_MODE_IDLE). To reactivate the CCS811 in the previous measurement mode, the ccs811_power_up function has to be used.

Note
It may take several minutes before accurate readings are generated when the sensor switches back from idle mode to the previous measurement mode. Therefore, the best power-saving solution is to leave the sensor in any measurement mode and to use it with data-ready interrupt (CCS811_INT_DATA_READY) in conjunction with the nWAKE signal pin.

<a name="baseline"> Baseline </a>    [<a href="#toc">TOC</a>]

CCS81 supports automatic baseline correction over a minimum time of 24 hours. Using function ccs811_get_baseline, the current baseline value can be saved before the sensor is powered down. This baseline can then be restored with function ccs811_set_baseline after sensor is powered up again to continue the automatic baseline process.

Note
This feature can only be used with the ccs811_full module.

<a name="error_handling"> Error Handling </a>    [<a href="#toc">TOC</a>]

All driver functions return an error code (ccs811_error_codes_t) to indicate whether its execution was successful or an error happened.

<a name="configuration"> Configuration </a>    [<a href="#toc">TOC</a>]

<a name="hardware_configuration"> Hardware Configurations </a>    [<a href="#toc">TOC</a>]

The following figure shows the most simple hardware configuration with CCS811. With this configuration interrupts, the hardware reset, and the sleep mode of the sensor with wake-up feature can't be used. The signals nINT** and nRESET are not connected. The nWAKE signal is permanently pulled low, leaving the CCS811 and I2C constantly active.

+--------+ +--------+
| MCU | | CCS811 |
| | | |
| SCL >-------> SCL |
| SDA <-------> SDA |
| GND --------> /WAKE |
+--------+ +--------+

If the interrupt signal nINT is used to fetch new data (only with ccs811_full module), the interrupt pin has to be connected to a GPIO pin.

+--------+ +--------+
| MCU | | CCS811 |
| | | |
| SCL >-------> SCL |
| SDA <-------> SDA |
| GPIO <-------> /INT |
| GND --------> /WAKE |
+--------+ +--------+

To use the hardware reset and/or the sleep mode with wake-up feature, additional GPIOs have to be used. This is the most energy-efficient hardware configuration of the sensor but requires more GPIO pins. Used GPIOs must be configured accordingly in driver configuration parameters.

+--------+ +--------+
| MCU | | CCS811 |
| | | |
| SCL >-------> SCL |
| SDA <-------> SDA |
| GPIOx <-------> /INT |
| GPIOy --------> /WAKE |
| GPIOz --------> /RESET |
+--------+ +--------+

If CCS811 sensor is used in conjunction with another sensor, e.g., a SHT3x sensor, the hardware configuration looks like following:

+--------+ +--------+
| MCU | | CCS811 |
| | | |
| SCL >--+----> SCL |
| SDA <--|-+--> SDA |
| GND ---|-|--> /WAKE |
| | | | +--------+
| | | | | SHT3x |
| | | | | |
| | +----> SCL |
| | +--> SDA |
+--------+ +--------+

<a name="driver_configuration"> Driver Configuration Parameters </a>    [<a href="#toc">TOC</a>]

The following configuration parameters can be used to configure the sensor during its initialization (ccs811_init):

Parameter Member Define macro Default
I2C device ccs811_params_t::i2c_dev CCS811_PARAM_I2C_DEV I2C_DEV(0)
I2C slave address ccs811_params_t::i2c_addr CCS811_PARAM_I2C_ADDR CCS811_I2C_ADDRESS_1
Measurement mode ccs811_params_t::mode CCS811_PARAM_MODE CCS811_MODE_1S
Interrupt mode ccs811_params_t::int_mode CCS811_PARAM_INT_MODE CCS811_INT_NONE
Interrupt pin ccs811_params_t::int_pin CCS811_PARAM_INT_PIN GPIO_PIN(0, 0)
Wake-up pin ccs811_params_t::wake_pin CCS811_PARAM_WAKE_PIN GPIO_UNDEF
Reset pin ccs811_params_t::reset_pin CCS811_PARAM_RESET_PIN GPIO_UNDEF

The default configuration of these parameters can be overridden by defining according macros before including ccs811_params.h, for example:

#define CCS811_PARAM_I2C_DEV (I2C_DEV(1))
#define CCS811_PARAM_I2C_ADDR (CCS811_I2C_ADDRESS_2)
#define CCS811_PARAM_MODE (CCS811_MODE_10S)
#define CCS811_PARAM_RESET_PIN (GPIO_PIN(0, 0))
#define CCS811_PARAM_WAKE_PIN (GPIO_PIN(0, 1))
#define CCS811_PARAM_INT_PIN (GPIO_PIN(0, 2))
#define CCS811_PARAM_INT_MODE (CCS811_INT_DATA_READY)
...
#include "ccs811.h"
#include "ccs811_params.h"

Alternatively, the complete set of default configuration parameters could also be overridden by a single definition, for example:

#define CCS811_PARAMS { .i2c_dev = I2C, \
.i2c_addr = CCS811_I2C_ADDRESS_2, \
.mode = CCS811_MODE_10S, \
.reset_pin = GPIO_PIN(0, 0), \
.wake_pin = GPIO_PIN(0, 1), \
.int_pin = GPIO_PIN(0, 2), \
.int_mode = CCS811_INT_DATA_READY, \
}

Files

file  ccs811_params.h
 Default configuration for AMS CCS811 digital gas sensors.
 
file  ccs811_regs.h
 Register definitions for the AMS CCS811 digital gas sensor.
 
file  ccs811.h
 Device Driver for AMS CCS811 digital gas sensor.
 
GPIO
#define GPIO
GPIO register bank.
Definition: cc26xx_cc13xx_gpio.h:55
ccs811_set_int_mode
int ccs811_set_int_mode(ccs811_t *dev, ccs811_int_mode_t mode)
Enable/disable data ready or threshold interrupt signal nINT
ccs811_read_ntc
int ccs811_read_ntc(const ccs811_t *dev, uint32_t r_ref, uint32_t *r_ntc)
Read the resistance of connected NTC thermistor.
ccs811_params.h
Default configuration for AMS CCS811 digital gas sensors.
ccs811_set_environmental_data
int ccs811_set_environmental_data(const ccs811_t *dev, int16_t temp, int16_t hum)
Set environmental data.
INT
@ INT
Interrupt.
Definition: cc2538_rfcore.h:234
log
Empty log structure.
Definition: dpl_log.h:41
ccs811_read_iaq
int ccs811_read_iaq(const ccs811_t *dev, uint16_t *iaq_tvoc, uint16_t *iaq_eco2, uint16_t *raw_i, uint16_t *raw_v)
Read IAQ sensor values and/or RAW sensor data.
CCS811_INT_THRESHOLD
@ CCS811_INT_THRESHOLD
nINT signal when new data reach thresholds
Definition: ccs811.h:87
ccs811_data_ready
int ccs811_data_ready(const ccs811_t *dev)
Data-ready status function.
CCS811_OK
@ CCS811_OK
no error
Definition: ccs811.h:51
CCS811_INT_DATA_READY
@ CCS811_INT_DATA_READY
nINT signal when new data are reade to read
Definition: ccs811.h:86