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.
/****************************************************************************** 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 //#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.