CCS811 Air Quality Breakout Hookup Guide
Example: Compensating for Climate
To have the CCS811 compensate for pressure and temperature conditions, obtain those metrics and pass to the sensor object with setEnvironmentalData
.
The examples from the library show three different sources of data that can be used to calibrate the CCS811:
- Randomly generated temperature and humidity data
- Data from a supplemental BME280 sensor
- Data collected by reading the NTC pins (No longer supported)
This guide only shows the example that uses randomized data, as it can be used without additional components yet still illustrate the effects of different climates.
From Arduino Library and Usage,
status_t setEnvironmentalData( float relativeHumidity, float temperature )
--- Sets the environmental conditions for compensation.- relativeHumidity in units of %, 0.00 through 100.0
- temperature in degrees C, -25.0 through 50.0
Compensating with Random Data
A starting place for working with the compensation is the setEnvironmentalReadings example. After the same configuration from the basic example, this sketch applies a random temperature and humidity, then takes 10 reads and repeats.
language:c
/******************************************************************************
setEnvironmentalReadings.ino
Marshall Taylor @ SparkFun Electronics
April 4, 2017
https://github.com/sparkfun/CCS811_Air_Quality_Breakout
https://github.com/sparkfun/SparkFun_CCS811_Arduino_Library
Hardware Connections (Breakoutboard to Arduino):
3.3V to 3.3V pin
GND to GND pin
SDA to A4
SCL to A5
Generates random temperature and humidity data, and uses it to compensate the CCS811.
This just demonstrates how the algorithm responds to various compensation points.
Use NTCCompensated or BME280Compensated for real-world examples.
Resources:
Uses Wire.h for i2c operation
Development environment specifics:
Arduino IDE 1.8.1
This code is released under the [MIT License](http://opensource.org/licenses/MIT).
Please review the LICENSE.md file included with this example. If you have any questions
or concerns with licensing, please contact techsupport@sparkfun.com.
Distributed as-is; no warranty is given.
******************************************************************************/
float temperatureVariable = 25.0; //in degrees C
float humidityVariable = 65.0; //in % relative
#include <Wire.h>
#include "SparkFunCCS811.h"
#define CCS811_ADDR 0x5B //Default I2C Address
//#define CCS811_ADDR 0x5A //Alternate I2C Address
CCS811 myCCS811(CCS811_ADDR);
void setup()
{
Serial.begin(9600);
Serial.println("CCS811 EnvironmentalReadings Example");
//This begins the CCS811 sensor and prints error status of .begin()
CCS811Core::status returnCode = myCCS811.begin();
Serial.print("begin exited with: ");
printDriverError( returnCode );
Serial.println();
}
void loop()
{
Serial.println();
//Randomize the Temperature and Humidity
humidityVariable = (float)random(0, 10000)/100; //0 to 100%
temperatureVariable = (float)random(500, 7000)/100; // 5C to 70C
Serial.println("New humidity and temperature:");
Serial.print(" Humidity: ");
Serial.print(humidityVariable, 2);
Serial.println("% relative");
Serial.print(" Temperature: ");
Serial.print(temperatureVariable, 2);
Serial.println(" degrees C");
myCCS811.setEnvironmentalData(humidityVariable, temperatureVariable);
Serial.println("Environmental data applied!");
myCCS811.readAlgorithmResults(); //Dump a reading and wait
delay(1000);
//Print data points
for( int i = 0; i < 10; i++)
{
if (myCCS811.dataAvailable())
{
//Calling readAlgorithmResults() function updates the global tVOC and CO2 variables
myCCS811.readAlgorithmResults();
Serial.print("CO2[");
Serial.print(myCCS811.getCO2());
Serial.print("] tVOC[");
Serial.print(myCCS811.getTVOC());
Serial.print("] millis[");
Serial.print(millis());
Serial.print("]");
Serial.println();
}
else if (myCCS811.checkForStatusError())
{
//If the CCS811 found an internal error, print it.
printSensorError();
}
delay(1000); //Wait for next reading
}
}
//printDriverError decodes the CCS811Core::status type and prints the
//type of error to the serial terminal.
//
//Save the return value of any function of type CCS811Core::status, then pass
//to this function to see what the output was.
void printDriverError( CCS811Core::status errorCode )
{
switch( errorCode )
{
case CCS811Core::SENSOR_SUCCESS:
Serial.print("SUCCESS");
break;
case CCS811Core::SENSOR_ID_ERROR:
Serial.print("ID_ERROR");
break;
case CCS811Core::SENSOR_I2C_ERROR:
Serial.print("I2C_ERROR");
break;
case CCS811Core::SENSOR_INTERNAL_ERROR:
Serial.print("INTERNAL_ERROR");
break;
case CCS811Core::SENSOR_GENERIC_ERROR:
Serial.print("GENERIC_ERROR");
break;
default:
Serial.print("Unspecified error.");
}
}
//printSensorError gets, clears, then prints the errors
//saved within the error register.
void printSensorError()
{
uint8_t error = myCCS811.getErrorRegister();
if( error == 0xFF )//comm error
{
Serial.println("Failed to get ERROR_ID register.");
}
else
{
Serial.print("Error: ");
if (error & 1 << 5) Serial.print("HeaterSupply");
if (error & 1 << 4) Serial.print("HeaterFault");
if (error & 1 << 3) Serial.print("MaxResistance");
if (error & 1 << 2) Serial.print("MeasModeInvalid");
if (error & 1 << 1) Serial.print("ReadRegInvalid");
if (error & 1 << 0) Serial.print("MsgInvalid");
Serial.println();
}
}
Compensating with BME280 Data
If you have a BME280 sensor, they work great for getting the compensation parameters. Use the example BME280Compensated to see compensation using another sensor.
Connecting the two devices is as simple as putting them on the bus together.
View BME280Compensated.ino on github, or use the example from Arduino.
Compensating from NTC Thermistor Readings
Alternately, an NTC resistor can be placed in the provided PTH terminals, and the example PTHCompensated can be used to see how the internal ADC is used to calibrate for temperature only.
There is one caveat to this method: no humidity data! Partially compensated is better than uncompensated, so punch in an average humidity for your area, or leave the example's default at 50 percent.
View NTCCompensated.ino on github, or use the example from Arduino.