AVRly - AVR Development Resources
ccs811.h File Reference

Driver for the CCS811 gas sensor . More...

#include <stdbool.h>
#include <stdint.h>

Go to the source code of this file.

Classes

struct  ccs811_config_t
 Config object, to be instantiated and values assigned to members before passing the object address into the function init_ccs811(). More...
 

Enumerations

enum  ccs811_drive_mode_t { drive_mode_idle = 0U , drive_mode_1sec = 1U , drive_mode_10sec = 2U , drive_mode_60sec = 3U }
 Drive modes 0 to 3. More...
 

Functions

uint8_t init_ccs811 (ccs811_config_t *p_config)
 Initialisation routine (run once at startup). More...
 
uint16_t ccs811_get_eco2_level (void)
 Read eCO2 (equivalent carbon dioxide) level from sensor. More...
 
uint16_t ccs811_get_etvoc_level (void)
 Read eTVOC (equivalent total volatile organic compounds) level from sensor. More...
 
void ccs811_get_alg_result_data (void)
 Perform a read operation on all 8 bytes of ALG_RESULT_REGISTER. More...
 
bool ccs811_data_ready_check (void)
 Read the status register and check if the data ready flag is set. More...
 
void ccs811_update_env_data (uint8_t humidity, uint8_t temp)
 (Optional) Write environmental data from another sensor to the CCS811. More...
 
char * ccs811_error_to_string (void)
 For error handling/logging. More...
 

Detailed Description

Driver for the CCS811 gas sensor .

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Author
Jason Duffy
Date
4th March 2022

This file provides the basic low-level functionality for the CCS81 gas sensor / air quality sensor. It was tested with the CJMCU-811 module which provides pin breakout to THT for breadboard prototyping, and some peripheral circuitry. The CCS811 eatures an on-board MCU to interface with, greatly reducing the load on the host MCU.

When the sensor is new, a burn-in period of 48hr is necessary for the resistive elements to level out and make readings more accurate. The CCS81 controls the burn-in period, allowing eCO2 and eTVOC readings to be used from first power-on after 60 minutes of operation in modes 1-3.

After early-life (Burn-In) use the conditioning period is the time required to achieve good sensor stability before measuring VOCs after a long idle period. After starting the application and calling init_ccs811(), run the sensor for 20 minutes before accurate readings are generated. The conditioning period must also be observed before writing to the BASELINE register.

This driver was written using the datasheet for the ams CCS81 gas sensor, which can be found at the link below.

See also
https://pdf1.alldatasheet.com/datasheet-pdf/view/1047395/AMSCO/CCS811.html

Definition in file ccs811.h.

Enumeration Type Documentation

◆ ccs811_drive_mode_t

Drive modes 0 to 3.

Mode 4 has been omitted as it does not appear to be particularly useful (only RAW_DATA may be used in mode 4).

Definition at line 66 of file ccs811.h.

67{
68 drive_mode_idle = 0U,
69 drive_mode_1sec = 1U,
70 drive_mode_10sec = 2U,
71 drive_mode_60sec = 3U,
ccs811_drive_mode_t
Drive modes 0 to 3.
Definition: ccs811.h:67

Function Documentation

◆ init_ccs811()

uint8_t init_ccs811 ( ccs811_config_t p_config)

Initialisation routine (run once at startup).

This function is to be called before any other functions in this file can be called. Instantiate the ccs811_config_t object first, then pass it's address into init_ccs811() to make config data available at file scope.

Parameters
p_configis a pointer to the ccs811_config_t object.
Returns
An error code is returned as an unsigned 8 bit integer.

Definition at line 133 of file ccs811.c.

134{
135 p_config_global = p_config; // Make a copy of pointer with file scope.
136 uint8_t ret = 0; // For return value
137 init_i2c(BUS_SPEED_100KHZ);
138 if (ccs811_read_byte(HW_ID_REG) == CCS811_ID)
139 {
140 uint8_t status = ccs811_get_status();
141 if (bit_is_set(status, APP_VALID_BIT))
142 {
143 i2c_start();
144 i2c_send(CCS811_ADDRESS_W);
145 i2c_send(APP_START);
146 i2c_stop();
147 _delay_ms(100);
148
149 uint8_t byte = 0;
150 byte |= (p_config_global->drive_mode << DRIVE_MODE_BITS);
151 byte |= (p_config_global->interrupt_dataready << INT_DATARDY_BIT);
152 byte |= (p_config_global->interrupt_threshold <<INT_THRESH_BIT);
153
154 for (uint8_t count = 0; count < ATTEMPTS_MAX; ++count)
155 {
156 ccs811_write_byte(MEAS_MODE_REG, byte);
157 _delay_ms(500);
158 uint8_t mode = ccs811_read_byte(MEAS_MODE_REG);
159 if (mode == byte)
160 {
161 break; // Success
162 }
163 if (count == (ATTEMPTS_MAX - 1))
164 {
165 ret = 3; // Max attempts reached
166 }
167 }
168 }
169 else
170 {
171 ret = 2; // Error - app invalid
172 }
173 }
174 else
175 {
176 ret = 1; // ccs81 ID failed
177 }
178 return ret;
179}
void init_i2c(uint32_t bus_speed)
Sets pullups and initializes i2c clock to desired bus speed.
Definition: atmega_i2c.c:49
void i2c_stop(void)
Sends a stop condition (sets TWSTO).
Definition: atmega_i2c.c:80
void i2c_send(uint8_t data)
Loads data, sends it out, waiting for completion.
Definition: atmega_i2c.c:90
void i2c_start(void)
Sends a start condition (sets TWSTA).
Definition: atmega_i2c.c:70

◆ ccs811_get_eco2_level()

uint16_t ccs811_get_eco2_level ( void  )

Read eCO2 (equivalent carbon dioxide) level from sensor.

Once the data_ready flag is set, this function can be called.

Returns
eCO2 level in ppm is returned, ranging from (400 - 32768ppm).

Definition at line 182 of file ccs811.c.

183{
184 uint16_t data = ccs811_read_word(ALG_RESULT_DATA_REG);
185 return data;
186}

◆ ccs811_get_etvoc_level()

uint16_t ccs811_get_etvoc_level ( void  )

Read eTVOC (equivalent total volatile organic compounds) level from sensor.

Once the data_ready flag is set, this function can be called.

Returns
eTVOC level in ppb is returned, ranging from (0 - 32768ppb).

Definition at line 189 of file ccs811.c.

190{
191 uint8_t data = 0;
192 ccs811_burst_read(ALG_RESULT_DATA_REG, ETVOC_SIZE);
193 uint8_t msb = read_buffer[ETVOC_SIZE - 2];
194 data = read_buffer[ETVOC_SIZE - 1];
195 data |= (msb << 8);
196 return data;
197}

◆ ccs811_get_alg_result_data()

void ccs811_get_alg_result_data ( void  )

Perform a read operation on all 8 bytes of ALG_RESULT_REGISTER.

The data is stored in the read_buffer[] array, and can be extracted using the register size definitions in the source file.

Definition at line 211 of file ccs811.c.

212{
213 ccs811_burst_read(ALG_RESULT_DATA_REG, ALG_RESULT_DATA_SIZE);
214}

◆ ccs811_data_ready_check()

bool ccs811_data_ready_check ( void  )

Read the status register and check if the data ready flag is set.

Use this function to poll the data ready flag and call the getter functions above only when a new value is ready.

Returns
A boolean value of true is returned if flag is set, otherwise false is returned.

Definition at line 200 of file ccs811.c.

201{
202 bool ret = false;
203 uint8_t status = ccs811_get_status();
204 if (bit_is_set(status, DATA_READY_BIT))
205 {
206 ret = true;
207 }
208 return ret;
209}

◆ ccs811_update_env_data()

void ccs811_update_env_data ( uint8_t  humidity,
uint8_t  temp 
)

(Optional) Write environmental data from another sensor to the CCS811.

The sensor has the capability to use humidity and temperature data in a compensation formula to imporve the accuracy of it's readings.

Parameters
uint8_thumidity is the Relative Humidity % passed in as an integer.
uint8_ttemp is the temperature in degrees Celcius.

Definition at line 216 of file ccs811.c.

217{
218 uint8_t lsb = 0;
219
220 i2c_start();
221 i2c_send(CCS811_ADDRESS_W);
222 i2c_send(ENV_DATA_REG);
223 i2c_send(humidity << 1);
224 i2c_send(lsb);
225 i2c_send(((temp + 25) << 1));
226 i2c_send(lsb);
227 i2c_stop();
228}

◆ ccs811_error_to_string()

char * ccs811_error_to_string ( void  )

For error handling/logging.

If the error flag is set on the status register, call this function to turn the error code into a string message.

Parameters
char*pointer to the first element of the string is returned.

Definition at line 231 of file ccs811.c.

232{
233 char *msg;
234 uint8_t error = ccs811_read_byte(ERROR_ID_REG);
235 if (bit_is_set(error, HEATER_SUPPLY))
236 {
237 msg = "Heater Supply";
238 }
239 else if (bit_is_set(error, HEATER_FAULT))
240 {
241 msg = "Heater Fault";
242 }
243 else if (bit_is_set(error, MAX_RESISTANCE))
244 {
245 msg = "Max Resistance";
246 }
247 else if (bit_is_set(error, MEASMODE_INVALID))
248 {
249 msg = "Invalid Meas Mode";
250 }
251 else if (bit_is_set(error, READ_REG_INVALID))
252 {
253 msg = "Read Reg Invalid";
254 }
255 else if (bit_is_set(error, WRITE_REG_INVALID))
256 {
257 msg = "Write Reg Invalid";
258 }
259 else
260 {
261 msg = "Unknown Error";
262 }
263 return msg;
264}