SparkFun Electronics 的 CCS811 Air Quality Breakout Hookup Guide 规格书

SEN-14193
CCS811 Air Quality Breakout Hookup Guide
Introduction
The CCS811 Air Quality Breakout is a digital gas sensor solution that senses a wide range of Total
Volatile Organic Compounds (TVOCs), including equivalent carbon dioxide (eCO2) and metal oxide
(MOX) levels. It is intended for indoor air quality monitoring in personal devices such as watches and
phones, but we’ve put it on a breakout board so you can use it as a regular I2C device.
SparkFun Air Quality Breakout - CCS811
SEN-14193
CC8811 Air Quality Breakout Hookup Guide SpurkFun wm stt 03 uar...
Required Materials
To follow along with this project tutorial, you will need the following materials:
CCS811 Air Quality Breakout Hookup Guide SparkFun Wish List
SparkFun RedBoard - Programmed with Arduino DEV-13975At SparkFun we use many Arduinos
and we're always looking for the simplest, most stable one. Each board is a bit different and no one board has
everyt…
Jumper Wires Premium 6" M/M Pack of 10 PRT-08431This is a SparkFun exclusive! These are
155mm long jumpers with male connectors on both ends. Use these to jumper from any female header on any
board,…
Break Away Headers - Straight PRT-00116A row of headers - break to fit. 40 pins that can be cut to
any size. Used with custom PCBs or general custom headers.**Features: *** Pin Style: Squar…
Breadboard - Self-Adhesive (White) PRT-12002This is your tried and true white solderless
breadboard. It has 2 power buses, 10 columns, and 30 rows - a total of 400 tie in points. All pins are sp
Resistor Kit - 1/4W (500 total) COM-10969Resistors are a good thing, in fact, they're actually crucial in
a lot of circuit designs. The only problem seems to be that resistors disappear into …
View CCS811 Air Quality Breakout Hookup Guide on SparkFun.com
Suggested Reading
If you aren’t familiar with the following concepts, we recommend checking out these tutorials before
continuing.
How to Solder: Through-Hole Soldering
This tutorial covers everything you need to know about through-hole soldering.
Installing an Arduino Library
How do I install a custom Arduino library? It's easy!
Co ntrol smals —> (CONN!) NTC thermistor I20 interface, _, connection power(3.3V). ground (Och-l) Address select Open for 0x58, closed for OX5A PLfl-Up dlsconnect (um rte-n luv mm- use)
How to Use a Breadboard
Welcome to the wonderful world of breadboards. Here we will learn what a breadboard is and how to
use one to build your very first circuit.
I2C
An introduction to I2C, one of the main embedded communications protocols in use today.
Hardware Overview
The CCS811 is supported by only a few passives, and so the breakout board is relatively simple.
This section discusses the various pins on the board.
Connections available to the user are shown on the top side
Jumpers are available on the bottom
Pins
Pin Description Direction
RST Reset (active low) In
INT Interrupt (active low) Out
WAK Wake (active low) In
SCL Clock In
SDA Data In
3.3V Power In
GND Ground In
NTC (2 pins) Negative thermal coefficient resistor N/A
Power and I2C Bus
The minimum required connections are power, ground SDA and SCL. Supply a regulated 3.3V
between the board’s 3.3V pin and ground terminals. The sensor consumes an average of 12mA of
current.
The I2C bus has pull-up resistors enabled by default. If not desired, these can be removed by
separating the “I2C PU” triple jumper on the bottom side with a hobby knife.
An I2C address can be either 0x5A or 0x5B. The “ADDR” jumper is connected with copper from the
factory, corresponding to a default address of 0x5B. Separate this jumper to use the address 0x5A.
Settling time: This sensor takes about 20 minutes to get fully settled to a point where it generates
good data. The I2C bus is active, and data can be collected before the 20 minutes is up, but it may
not be accurate.
Control lines
Additionally, the three control lines RST, INT and WAK can be used to further the degree of control.
RST — Pull this line low to reset the IC.
INT — After configuring the sensor to emit interrupt requests, read this line to determine the
state of the interrupt.
WAK — Pull this line high to put the sensor to sleep. This can be used to save power but is not
necessary if power is not an issue.
NTC Thermistor operation
A thermistor can be used to determine the temperature of the CCS811’s surroundings, which can be
used to help compensate the readings. You’ll need your own 10K NTC thermistor, such as our 10K
Thermistor, soldered between the “NTC” pins. A thermistor is a nonpolarized device, so it can go in
either way.
Hardware Assembly
Attach Headers
To prepare the sensor for the examples, attach seven pins from a Break Away Header to the
through holes. Even though we only need the four I2C pins, we’ll populate all of them for this guide in
case we want to try them out.
Place the strip of seven pins in a breadboard.
Solder a single pin and then check that the board is square to the pins.
Solder the remaining pins.
Attach NTC thermistor (Optional)
If you would like to use a thermistor to compensate for temperature, solder in a 10K Thermistor
(Vishay part number NTCLE100E3103JB0).
Attaching an NTC thermistor
Example Assemblies
You’re ready to start communicating with the CCS811! Here’s an example with the NTC Thermistor
populated, and one using right-angle headers instead.
Arduino Library and Usage
Getting the CCS811 Arduino Library
To get the Arduino library, download from GitHub or use the Arduino Library Manager.
Download the GitHub repository
Visit the GitHub repository to download the most recent version of the library, or click the button
below:
DOWNLOAD THE SPARKFUN CCS811 ARDUINO LIBRARY
https://github.com/sparkfun/SparkFun_CCS811_Arduino_Library/archive/master.zip
#include (SparkFunCC5811.h> #define CC5811_ADDR 9X53 //De‘Fault 12C Address //#define CC5811_AD void loop() ( if (myccsan,aataAvanableO) { myCCSBll.readAlgorithmResultsO; int tempCOZ : m
Use the Library Manager or install in the Arduino IDE
For help installing the library, check out our Installing an Arduino Library tutorial.
https://learn.sparkfun.com/tutorials/installing-an-arduino-library
If you don’t end up using the manager, you’ll need to move the SparkFun_CCS811_Arduino_Library
folder into a libraries folder within your Arduino sketchbook. If you downloaded the zip, you can
remove “master” from the name, but it’s not required.
Using the Library
The library is fairly normal to use compared with our other sensors. You’ll have to include the library,
create a sensor object in the global space, and then use functions of that object to begin and control
the sensor. With this one, pass the I2C address must to the object during construction.
To get the library included, and to take care of all the gritty compiler stuff, place the following at the
beginning of the sketch before voidsetup()
CopyCode
#include<SparkFunCCS811.h>#defineCCS811_ADDR0x5B//DefaultI2CAddress//#defineCCS811_AD
DR0x5A//AlternateI2CAddressCCS811myCCS811(CCS811_ADDR);
Now, functions of the object named myCCS811 can be called to set up and get data, while all the wire
stuff is kept under the hood.
To make the sensor get ready during program boot, myCCS811.begin() must be called. Here’s an
example of the minimal usage of begin.
Error Status: The .begin() function has a special feature: it returns the status of the function call! If
there was a problem during begin, it will return a non-zero code indicating what happened. It's
optional, and is described in the "Custom Types and Literals" section below.
CopyCode
voidsetup(){myCCS811.begin();}
Then, in the main loop of the program, call sensor functions such as
mySensor.readAlgorithmResults() to operate the sensor. The following snippet shows a simple
check for data, to call on the sensor to calculate and get values, and to access those values. It
doesn’t do anything with the data, though! Check out the examples for fully functional code.
CopyCode
voidloop(){if(myCCS811.dataAvailable()){myCCS811.readAlgorithmResults();inttempCO2=m
yCCS811.getCO2();inttempVOC=myCCS811.gettVOC();}elseif(myCCS811.checkForStatusError())
{while(1);}delay(1000);//Waitfornextreading}
Function Reference
The following functions exist for the CCS811 object.
Functions with scoped return type CCS811Core::status report an error state as defined in the literals
section below. It is optional and can be used to determine success or failure of call.
CCS811Core::statusbegin(void) — This starts wire, checks the ID register, checks for valid
app data, starts the app, and establishes a drive mode.
CCS811Core::statusreadAlgorithmResults(void) — Call to cause the sensor to read its
hardware and calculate TVOC and eCO2 levels.
boolcheckForStatusError(void) — Returns true if there is an error pending. This checks
the status register.
booldataAvailable(void) — Returns true if a new sample is ready and hasn’t been read.
boolappValid(void) — Returns true if there is a valid application within the internal
CCS811 memory.
uint8_tgetErrorRegister(void) — Returns the state of the ERROR_ID register.
uint16_tgetBaseline(void) — Returns the baseline value.
CCS811Core::statussetBaseline(uint16_t) — Apply a saved baseline to the CCS811.
CCS811Core::statusenableInterrupts(void) — Enables the interrupt pin for data ready.
CCS811Core::statusdisableInterrupts(void) — Disables the interrupt pin.
CCS811Core::statussetDriveMode(uint8_tmode) — Sets the drive mode (mode can be 0
through 4).
o 0: Measurement off
o 1: Measurement every 1 second
o 2: Measurement every 10 seconds
o 3: Measurement every 60 seconds
o 4: Measurement every 0.25 seconds — for use with external algorithms
CCS811Core::statussetEnvironmentalData(floatrelativeHumidity,floattemperature)
— Sets the environmental conditions for compensation.
o relativeHumidity in units of %, 0.00 through 100.0
o temperature in degrees C, -25.0 through 50.0
voidsetRefResistance(float) — If you’ve changed the thermistor pull-up, call this to give
the sensor the new resistor value. Otherwise, it will be 10000.
CCS811Core::statusreadNTC(void) — Cause the CCS811 to get and calculate a
temperature from the thermistor input.
uint16_tgetTVOC(void) — Collect the last calculated TVOC value, in parts per billion (ppb).
uint16_tgetCO2(void) — Collect the last calculated eC02 value, in parts per million (ppm).
floatgetResistance(void) — Collect the last calculated resistance value of the NTC
terminals.
floatgetTemperature(void) — Collect the last calculated temperature.
// Return values typedef enum ( SENSOR_SUCCESS, SENSOR_ID_ERROR, SENSOR_IZC_ERROR, SENSOR_INTE Switch ( Petur‘nCode ) { case CCSEllcol‘e::SENSOR_SUCCESSI Serial.pl‘int("SUCCESS"); break; case ERNAL_ERROR"); break; case CCSBllcol‘e::SENSOR_GENERIC_ERROR: Serial,pr‘int("GENERIC_ERROR"); br‘ LG_RESULT_DATA 8X91 “define C55811_RAW_DATA 8X83 #define C55811_ENV_DATA 0X85 #define C55811_N #deffine C55811_HW_VERSION 8X11 “define C55811_FW_BOOT_VERSION 0x23 #define C55811_F|M_APP_VERSI
Custom Types and Literals
The CCS811 library defines the following special data type to deal with error states of functions. In
most places the library can be used without paying attention to the function return types, but if they
are needed, here are the values the data type status can hold:
CopyCode
//Returnvaluestypedefenum{SENSOR_SUCCESS,SENSOR_ID_ERROR,SENSOR_I2C_ERROR,SENSOR_INTE
RNAL_ERROR//...}status;
To avoid the possibility of multiple libraries using the same status name, the enum is actually inside
the scope of the CCS811 object, buried in the CCS811Core, which is the base class. Phew, don’t
worry about that too much; just place CCSCore:: before the status name when you want to use it, and
use it like a regular enum (e.g., CCS811Core::statusmyLocalReturnStatus;). This just tells the
compiler that the variable name is in a specific place. You’ll also have to add the scope operator to
the enum names.
Here’s an example that shows how the status enum can be used:
CopyCode
CCS811Core::statusreturnCode=mySensor.beginCore();Serial.print("beginCoreexitedwith:");
switch(returnCode){caseCCS811Core::SENSOR_SUCCESS:Serial.print("SUCCESS");break;case
CCS811Core::SENSOR_ID_ERROR:Serial.print("ID_ERROR");break;caseCCS811Core::SENSOR_I2C_ERRO
R:Serial.print("I2C_ERROR");break;caseCCS811Core::SENSOR_INTERNAL_ERROR:Serial.print("INT
ERNAL_ERROR");break;caseCCS811Core::SENSOR_GENERIC_ERROR:Serial.print("GENERIC_ERROR");br
eak;default:Serial.print("Unspecifiederror.");}
The library also defines names for CCS811 registers, if you’re using direct read and write functions.
These are globally scoped and can be used anywhere.
CopyCode
//Registeraddresses#defineCSS811_STATUS0x00#defineCSS811_MEAS_MODE0x01#defineCSS811_A
LG_RESULT_DATA0x02#defineCSS811_RAW_DATA0x03#defineCSS811_ENV_DATA0x05#defineCSS811_N
TC0x06#defineCSS811_THRESHOLDS0x10#defineCSS811_BASELINE0x11#defineCSS811_HW_ID0x20
#defineCSS811_HW_VERSION0x21#defineCSS811_FW_BOOT_VERSION0x23#defineCSS811_FW_APP_VERSI
ON0x24#defineCSS811_ERROR_ID0xE0#defineCSS811_APP_START0xF4#defineCSS811_SW_RESET0xF
F
Example: Basic Reading
After you’ve got pins attached to your breakout board, the first example to use should be
BasicReadings. Select it from examples or copy from below.
Connect the sensor as follows as a starting place for the examples.
fives“:ewuuweewuuuuwwxxxueewuuueeewuuueuuuuuwuum BasicReadingst C5811_Arduino_Library Read the TVOC and C02 Values From the SparkFun CSSBll breakout board Thi es or run in berore readings are considered gccdl Hardware connections (Breakoutboard to Ardui ion Development environment Specifics: Arduinc IDE 1i8,1 This code is released under the [MIT @Sparkfunlcomi Distributed as-is; no warranty is givent ~vvvvt***~~~verrrrrr~~verrrrrr~~eeerrr 1_ADDR); void setup() { Serialtbegin(9669); Serialtprintln("CC5811 Basic Example“); //It is re n error "); while (1); //Hang if tnere was a problemt } } void loop() ( //Check to see if data nd calculate tne resultst //Get them later mySensorireadAlgorjthmReSultS(); Serialtprint("C02[ //Simply the time since program start Serialiprint(millis()); Serial‘print(“]“); Serial printl
Wiring diagram showing basic connection to RedBoard. Click for a closer look.
For this example, only 3.3V, GND, SDA and SCL are needed. The jumpers on the board are left in
the default positions.
CopyCode
/******************************************************************************BasicReadings.
inoMarshallTaylor@SparkFunElectronicsNathanSeidle@SparkFunElectronicsApril4,2017
https://github.com/sparkfun/CCS811_Air_Quality_Breakouthttps://github.com/sparkfun/SparkFun_C
CS811_Arduino_LibraryReadtheTVOCandCO2valuesfromtheSparkFunCSS811breakoutboardThi
sisthesimplestexample.Itthrowsawaymosterrorinformationandrunsatthedefault1sam
plepersecond.Anewsensorrequiresat48burnin.Onceburnedinasensorrequires20minut
esofruninbeforereadingsareconsideredgood.HardwareConnections(BreakoutboardtoArdui
no):3.3Vto3.3VpinGNDtoGNDpinSDAtoA4SCLtoA5Resources:UsesWire.hfori2coperat
ionDevelopmentenvironmentspecifics:ArduinoIDE1.8.1Thiscodeisreleasedunderthe[MIT
License](http://opensource.org/licenses/MIT).PleasereviewtheLICENSE.mdfileincludedwith
thisexample.Ifyouhaveanyquestionsorconcernswithlicensing,pleasecontacttechsupport
@sparkfun.com.Distributedasis;nowarrantyisgiven.**************************************
****************************************/#include"SparkFunCCS811.h"#defineCCS811_ADDR0x5B
//DefaultI2CAddress//#defineCCS811_ADDR0x5A//AlternateI2CAddressCCS811mySensor(CCS81
1_ADDR);voidsetup(){Serial.begin(9600);Serial.println("CCS811BasicExample");//Itisre
commendedtocheckreturnstatuson.begin(),butitisnot//required.status_treturnCode=
mySensor.begin();if(returnCode!=SENSOR_SUCCESS){Serial.println(".begin()returnedwitha
nerror.");while(1);//Hangiftherewasaproblem.}}voidloop(){//Checktoseeifdata
isreadywith.dataAvailable()if(mySensor.dataAvailable()){//Ifso,havethesensorreada
ndcalculatetheresults.//GetthemlatermySensor.readAlgorithmResults();Serial.print("CO2[
");//ReturnscalculatedCO2readingSerial.print(mySensor.getCO2());Serial.print("]tVOC[");
//ReturnscalculatedTVOCreadingSerial.print(mySensor.getTVOC());Serial.print("]millis[");
//SimplythetimesinceprogramstartSerial.print(millis());Serial.print("]");Serial.printl
n();}delay(10);//Don'tspamtheI2Cbus}
eadAlgorit @ com; ocsa11 nan: Damp]: com] wowz] mnumm] com] wowz] m111:[2991] com] wowz] mnmms] mzunn] mzunn] m2un9] mzum] mzum] mzum] 0mm] 0mm] 0mm] mzufl] mzufl] 0mm] 0mm] wow] wow] wow] wow] wow] wow] wow] wow] wow] wow] wow] wow] wow] mm: [mm] mm: [59s5] mm: [sesn] mm: [7955] mm: [5959] mm: [995:] mm: [1mm mm: [11915] mm: [129n9] mm: [1559:] mm: [1.555] mm: [1555:] mm: [1s5s9] D mm: runs-in gamma
At the beginning, an object is created in the global space CCS811mySensor(CCS811_ADDR); and is
constructed with the address as a parameter. During the setup phase, the library is told to configure
with status_treturnCode=mySensor.begin(); Using the return parameter to check for errors is
optional, and in this example if the return code is not valid, the program enters a captive while loop.
To get data from the sensor, mySensor.dataAvailable() is checked until a new reading is ready,
mySensor.readAlgorithmResults(); is called to have the sensor process the reading, then
mySensor.getCO2() and mySensor.getTVOC() are used to retrieve the calculated values for gas
levels.
Example terminal output
If everything is connected correctly, the serial window will report gas levels every second.
Remember the sensor takes 20 minutes to properly warm up, so values reported will rise up in the
early stages of operation!
Summary:
To get data from the CCS811, these minimum requirements must be met:
Create a CCS811 object in the global space
Run .begin() of your object (Return type monitoring optional)
Check for the availability of new data with .dataAvailable()
Use .readAlgorithmResults() to perform a measurement
o .getCO2() to get the last equivalent CO2 reading (no I2C bus operation)
o .getTVOC() to get the last TVOC reading (no I2C bus operation)
Example: Additional Control Lines
The CCS811 has a couple extra control lines that are not part of the I2C bus, which can be utilized to
improve the system. There’s a pin to flag that data is ready, and a pin to make the sensor go to
sleep.
fritzing pttinc Marshall Taylor @ SparkFun Electronics April 4, 2617 https://githubtCom/sparkfun/CCSBII is ready to be collectedt The wake pin is configured to enable the sensor during 12c Communica mm | -------- NOT_WAKE \ R2 : 4‘7K | GND Resources: Uses Wireth For 12: operation Development openscurcetor‘g/licenseS/MIT)l Please review the LICENSEJnd file included with this example If *****"*”“***"*”*“/ ainclude (SparkFunCCSBILW #dew‘ine ccsaii_AuDR exsa //Default 12c Ad ................................ void setupo { //start the serial Serialtbeginfisee); Serialt with: ); pr‘intDriverError( returnCode ); SeriaLpr‘inth); //This sets the node to 66 second Mode request exited with: “),- printDriverError( returnCode ),- Serialspr‘intan; //Com=igure an rintDriverError( returnCode ),- Serial,println(); //Com=igure the wake line pinMode(PIN_NOT_wAK italRead ( PIN_NOT_INT) a) { //Wake up the ccsaii logic engine digitalm‘ite(PIN_NOT_wAKE, e);
Wiring diagram including the wake and interrupt pins. Click for a closer look.
To connect the interrupt line, connect it directly to an input pin. This is a 3.3V output from the sensor,
so it’s OK to drive the input logic of a 5V device from it. The example has nInt connected to pin 6.
To connect the wake stat line, use a voltage divider to divide the 5V coming from the Arduino down
to something below 3.3V for the sensor. The example has nWake connected to pin 5 through a
voltage divider made from two 4.7K resistors for a 2.5V output.
The example for these additional lines is called WakeAndInterrupt and is listed here:
CopyCode
/******************************************************************************WakeAndInterru
pt.inoMarshallTaylor@SparkFunElectronicsApril4,2017https://github.com/sparkfun/CCS811
_Air_Quality_Breakouthttps://github.com/sparkfun/SparkFun_CCS811_Arduino_LibraryThisexample
configuresthenWAKEandnINTpins.Theinterruptpinisconfiguredtopulllowwhenthedata
isreadytobecollected.ThewakepinisconfiguredtoenablethesensorduringI2Ccommunica
tionsHardwareConnections(BreakoutboardtoArduino):3.3Vto3.3VpinGNDtoGNDpinSDAto
A4SCLtoA5NOT_INTtoD6NOT_WAKEtoD5(For5Varduinos,useresistordivider)D5‐‐‐|R1=
4.7K|‐‐‐‐‐‐NOT_WAKE|R2=4.7K|GNDResources:UsesWire.hfori2coperationDevelopment
environmentspecifics:ArduinoIDE1.8.1Thiscodeisreleasedunderthe[MITLicense](http://
opensource.org/licenses/MIT).PleasereviewtheLICENSE.mdfileincludedwiththisexample.If
youhaveanyquestionsorconcernswithlicensing,pleasecontacttechsupport@sparkfun.com.Di
stributedasis;nowarrantyisgiven.*******************************************************
***********************/#include<SparkFunCCS811.h>#defineCCS811_ADDR0x5B//DefaultI2CAd
dress//#defineCCS811_ADDR0x5A//AlternateI2CAddress#definePIN_NOT_WAKE5#definePIN_NO
T_INT6CCS811myCCS811(CCS811_ADDR);//Globalsensorobject//‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐voidsetup(){//StarttheserialSerial.begin(9600);Serial.
println();Serial.println("...");status_treturnCode;//ThisbeginstheCCS811sensorandpri
ntserrorstatusof.begin()returnCode=myCCS811.begin();Serial.print("CCS811beginexited
with:");printDriverError(returnCode);Serial.println();//Thissetsthemodeto60second
reads,andprintsreturnederrorstatus.returnCode=myCCS811.setDriveMode(2);Serial.print("
Moderequestexitedwith:");printDriverError(returnCode);Serial.println();//Configurean
denabletheinterruptline,//thenprinterrorstatuspinMode(PIN_NOT_INT,INPUT_PULLUP);ret
urnCode=myCCS811.enableInterrupts();Serial.print("Interruptconfiguationexitedwith:");p
rintDriverError(returnCode);Serial.println();//ConfigurethewakelinepinMode(PIN_NOT_WAK
E,OUTPUT);digitalWrite(PIN_NOT_WAKE,1);//Startasleep}//‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐voidloop(){//LookforinterruptrequestfromCCS811if(dig
italRead(PIN_NOT_INT)==0){//WakeuptheCCS811logicenginedigitalWrite(PIN_NOT_WAKE,0);
//Needtowaitatleast50usdelay(1);//Interruptsignalcaught,socausetheCCS811torun
and coz variables Serial.print("coz["); Serial,print(nycc5811.getc02()); SeriaLprintC'] tvoc[ NOT_WAKE, 1); //Need to be asleep for at least 19 us delay(1); } delay(1); //cyc1e kinda Fast rninal, // //Save the return value of any function of type status_t, then pass //to this Funct ("ID_ERROR"); break; case SENSOR_IZC_ERROR: Serial.print("IZC_ERROR"); break; case SENSOR_INTE , clears, then prints the errors //saved within the error register, void printSensorErroro { er‘ial,print("Heater-Supply"); if (error a 1 < 4)="" serial,print("heaterfault-');="" if="" (error="" a="" 1="">< or="" a="" 1="">< 1)="" serialiprint("readregin\/alid");="" if="" (error="" a="" 1="">< 0)="" serial.print("msglnvalid");="" s="" a="" com="" —="" el="" x="" ccsell="" devin="" exited="" with:="" success="" hod:="" mil:="" exited="" with:="" success="" interrupt="" mimticm="" exited="" with:="" snows="" cozid]="" tvocld]="" nilli:[11296]="" cozid]="" tvocm]="" nilli:[21092]="" cozid]="" tvocm]="" nilli:[30!39]="" cozijdo]="" tvocld]="" milliauflfifib]="" cozigbz]="" tvocll4]="" millisismeg]="" cozijzo]="" tvocls]="" nilli:[6|7264]="" c02[409]="" tvocll]="" nilli:[7|7065]="" cozijzo]="" tvocls]="" nilli:[79366]="" dub-ad="" mona-vim="" v="" mm="" v="">
itsalgorithmmyCCS811.readAlgorithmResults();//CallingthisfunctionupdatestheglobaltVOC
andCO2variablesSerial.print("CO2[");Serial.print(myCCS811.getCO2());Serial.print("]tVOC[
");Serial.print(myCCS811.getTVOC());Serial.print("]millis[");Serial.print(millis());Seria
l.print("]");Serial.println();//NowputtheCCS811'slogicenginetosleepdigitalWrite(PIN_
NOT_WAKE,1);//Needtobeasleepforatleast20usdelay(1);}delay(1);//cyclekindafast
}//printDriverErrordecodesthestatus_ttypeandprintsthe//typeoferrortotheserialte
rminal.////Savethereturnvalueofanyfunctionoftypestatus_t,thenpass//tothisfunct
iontoseewhattheoutputwas.voidprintDriverError(status_terrorCode){switch(errorCo
de){caseSENSOR_SUCCESS:Serial.print("SUCCESS");break;caseSENSOR_ID_ERROR:Serial.print
("ID_ERROR");break;caseSENSOR_I2C_ERROR:Serial.print("I2C_ERROR");break;caseSENSOR_INTE
RNAL_ERROR:Serial.print("INTERNAL_ERROR");break;caseSENSOR_GENERIC_ERROR:Serial.print("GE
NERIC_ERROR");break;default:Serial.print("Unspecifiederror.");}}//printSensorErrorgets
,clears,thenprintstheerrors//savedwithintheerrorregister.voidprintSensorError(){
uint8_terror=myCCS811.getErrorRegister();if(error==0xFF)//commerror{Serial.printl
n("FailedtogetERROR_IDregister.");}else{Serial.print("Error:");if(error&1<<5)S
erial.print("HeaterSupply");if(error&1<<4)Serial.print("HeaterFault");if(error&1<<
3)Serial.print("MaxResistance");if(error&1<<2)Serial.print("MeasModeInvalid");if(err
or&1<<1)Serial.print("ReadRegInvalid");if(error&1<<0)Serial.print("MsgInvalid");S
erial.println();}}
Notice that this example doesn’t poll dataAvailable() to check if data is ready; instead it reads the
state of a digital input. When the input is low, data is ready in the sensor and
readAlgorithmResults(), then .getCO2() and getTVOC() are used as normal.
The WAK pin can be used to control the logic engine on the CCS811 to save a bit of power. When
the WAK pin is low (or disconnected), the I2C bus will respond to commands, but when the pin is
high it will not. Tens of microseconds are required to wake or sleep, so in this example, commands
are wrapped with a 1ms delay.
Example terminal output
The terminal displays the calculation every 10 seconds. You can see that it take a few samples for
the algorithm to spit out data, even at a slow rate of acquisition. Between the sampling, power is
decreased as much as possible.
Summary:
To use WAK,
Set up a digital output for the wake pin
To communicate with a sleeping sensor,
o Set WAK low
o Wait 50us
o Do your communication
o Set WAK high
o Wait 20us
To use INT,
Set up a digital input for the interrupt pin
Enable interrupts with enableInterrupts()
Look for a falling edge on the input to detect the availability of new data
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:
1. Randomly generated temperature and humidity data
2. Data from a supplemental BME280 sensor
3. Data collected by reading the NTC pins
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_tsetEnvironmentalData(floatrelativeHumidity,floattemperature) — Sets the
environmental conditions for compensation.
o relativeHumidity in units of %, 0.00 through 100.0
o 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.
n/ccsa11_Air_Qua1ity_Breakout https://github.ccm/sparkfun/SparkFun_CC5811_Arduino_Library Hard AS Generates random temperature and humidity data, and uses it to compensate the CCSEII, This opnent environment specifics: Arduino 155 1.8 1 This code is released under the [MIT License]( ‘wm' Distributed 3545; "a warranty is given. wwuuxwuwxxan”mum"ewwuwwww 1_ADDR 9X53 //DeFault IZC AddreSS //#define CC5811_ADDR BXSA //A1ternate 12C Address CC5811 my adings Example"); //This begins the ccss11 sensor and prints error status of sbegin() statvs_t dity humidityVariable : (F10at)randcm(e, 1eeee)/1ee; //e to 190% temperatureVariable : (float) int(" Temperature: "); Serialsprint(temperatureVariable, 2); Serial print1n(" degrees c"); myC Print data points for( int i : e; i < 19;="" i++)="" {="" if="" (mycc5811.dataavailable())="" {="" ca11ing="" rea="" esults();="" serial="" print("c02[");="" serialsprint(mycc5811.getc02());="" seria1.print("]="" tvoc[");="" seri="" interna1="" error,="" print="" it.="" printsensorerror();="" }="" deiay(1eee);="" wait="" for="" next="" reading="" }="" }="" pri="" ee="" what="" the="" output="" was.="" void="" printdrivererror(="" statvs_t="" errorcode="" )="" {="" switch(="" errorcode="" )="" {="" ca="" r:="" serialsprint("internal_error");="" break;="" case="" sensor_generic_error:="" serial,print("generic_err="" then="" prints="" the="" errors="" saved="" within="" the="" error="" register,="" void="" printsensorerrcr()="" (="" uints_t="" er="" heatersupply");="" if="" (error="" a="" 1="">< 4)="" serial.print("heaterfau1t");="" 1f="" (error="" a="" 1="">< 3)="" seria1.pr="">
CopyCode
/******************************************************************************setEnvironment
alReadings.inoMarshallTaylor@SparkFunElectronicsApril4,2017https://github.com/sparkfu
n/CCS811_Air_Quality_Breakouthttps://github.com/sparkfun/SparkFun_CCS811_Arduino_LibraryHard
wareConnections(BreakoutboardtoArduino):3.3Vto3.3VpinGNDtoGNDpinSDAtoA4SCLto
A5Generatesrandomtemperatureandhumiditydata,andusesittocompensatetheCCS811.This
justdemonstrateshowthealgorithmrespondstovariouscompensationpoints.UseNTCCompensate
dorBME280Compensatedforrealworldexamples.Resources:UsesWire.hfori2coperationDevel
opmentenvironmentspecifics:ArduinoIDE1.8.1Thiscodeisreleasedunderthe[MITLicense](
http://opensource.org/licenses/MIT).PleasereviewtheLICENSE.mdfileincludedwiththisexam
ple.Ifyouhaveanyquestionsorconcernswithlicensing,pleasecontacttechsupport@sparkfun
.com.Distributedasis;nowarrantyisgiven.***********************************************
*******************************/floattemperatureVariable=25.0;//indegreesCfloathumidi
tyVariable=65.0;//in%relative#include<Wire.h>#include"SparkFunCCS811.h"#defineCCS81
1_ADDR0x5B//DefaultI2CAddress//#defineCCS811_ADDR0x5A//AlternateI2CAddressCCS811my
CCS811(CCS811_ADDR);voidsetup(){Serial.begin(9600);Serial.println("CCS811EnvironmentalRe
adingsExample");//ThisbeginstheCCS811sensorandprintserrorstatusof.begin()status_t
returnCode=myCCS811.begin();Serial.print("beginexitedwith:");printDriverError(returnCo
de);Serial.println();}voidloop(){Serial.println();//RandomizetheTemperatureandHumi
dityhumidityVariable=(float)random(0,10000)/100;//0to100%temperatureVariable=(float)
random(500,7000)/100;//5Cto70CSerial.println("Newhumidityandtemperature:");Serial.pr
int("Humidity:");Serial.print(humidityVariable,2);Serial.println("%relative");Serial.pr
int("Temperature:");Serial.print(temperatureVariable,2);Serial.println("degreesC");myC
CS811.setEnvironmentalData(humidityVariable,temperatureVariable);Serial.println("Environment
aldataapplied!");myCCS811.readAlgorithmResults();//Dumpareadingandwaitdelay(1000);//
Printdatapointsfor(inti=0;i<10;i++){if(myCCS811.dataAvailable()){//Callingrea
dAlgorithmResults()functionupdatestheglobaltVOCandCO2variablesmyCCS811.readAlgorithmR
esults();Serial.print("CO2[");Serial.print(myCCS811.getCO2());Serial.print("]tVOC[");Seri
al.print(myCCS811.getTVOC());Serial.print("]millis[");Serial.print(millis());Serial.print(
"]");Serial.println();}elseif(myCCS811.checkForStatusError()){//IftheCCS811foundan
internalerror,printit.printSensorError();}delay(1000);//Waitfornextreading}}//pri
ntDriverErrordecodesthestatus_ttypeandprintsthe//typeoferrortotheserialterminal.
////Savethereturnvalueofanyfunctionoftypestatus_t,thenpass//tothisfunctiontos
eewhattheoutputwas.voidprintDriverError(status_terrorCode){switch(errorCode){ca
seSENSOR_SUCCESS:Serial.print("SUCCESS");break;caseSENSOR_ID_ERROR:Serial.print("ID_ERRO
R");break;caseSENSOR_I2C_ERROR:Serial.print("I2C_ERROR");break;caseSENSOR_INTERNAL_ERRO
R:Serial.print("INTERNAL_ERROR");break;caseSENSOR_GENERIC_ERROR:Serial.print("GENERIC_ERR
OR");break;default:Serial.print("Unspecifiederror.");}}//printSensorErrorgets,clears,
thenprintstheerrors//savedwithintheerrorregister.voidprintSensorError(){uint8_ter
ror=myCCS811.getErrorRegister();if(error==0xFF)//commerror{Serial.println("Failedto
getERROR_IDregister.");}else{Serial.print("Error:");if(error&1<<5)Serial.print("
HeaterSupply");if(error&1<<4)Serial.print("HeaterFault");if(error&1<<3)Serial.pr
int("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.
A BME280 used in conjunction with the CCS811
View BME280Compensated.ino on github, or use the example from Arduino.
https://github.com/sparkfun/SparkFun_CCS811_Arduino_Library/blob/master/examples/BME280Compensated/BME280Compensated.ino
Compensating from NTC Thermistor Readings
Alternately, an NTC resistor can be placed in the provide 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.
https://github.com/sparkfun/SparkFun_CCS811_Arduino_Library/blob/master/examples/NTCCompensated/NTCCompensated.ino
Resources and Going Further
Now that you’ve successfully got your CCS811 breakout up and running, and have scientifically
proved which family member is the smelliest, here are some additional resources:
CCS811 Datasheet-DS000459.pdf — PDF
ASHRAE Allowable CO2 Levels.pdf — PDF
CC-000774-AN-3-Assembly guidelines for CCS811.pdf — PDF
CC-000783-AN-1-Mechanical Considerations for CCS811_0.pdf — PDF
CCS811 Firmware Download AN000371.pdf — PDF
CCS811 Programming Guide-AN000369.pdf — PDF
CCS811 Thermistor Interface AN000372.pdf — PDF
Indoor Air Quality Investigations TVOCs EU.pdf — PDF
CCS811_Air_Quality_Breakout product repository — Design files and docs
SparkFun_CCS811_Arduino_Library Repository — Source and example files for the Arduino
library used in this tutorial.
Also, the following examples are included with the library but not discussed. They may help you on
your way!
BaselineOperator — Save and restore baselines to the EEPROM
Core — Show how the underlying hardware object works
TwentyMinuteTest — Report data with timestamp
Ardumo.
Need some inspiration for your next project? Check out some of these sensor-related tutorials:
MS5803-14BA Pressure Sensor Hookup Guide
Breakout of MS5803-14BA Pressure Sensor
TSL2561 Luminosity Sensor Hookup Guide
The TSL2561 is an light sensor that's very inexpensive for the accuracy it provides. Here's how to
use it.
MyoWare Muscle Sensor Kit
Line of products to work with the MyoWare muscle sensor from Advancer Technologies
TMP102 Digital Temperature Sensor Hookup Guide
How to connect and use the SparkFun Digital Temperature Sensor Breakout - TMP102 with an
Arduino.
https://learn.sparkfun.com/tutorials/ccs811airqualitybreakouthookupguide?_ga=1.221677976.1064614676.148822123842817