Adafruit_CCS811.h (7651B)
1 #ifndef LIB_ADAFRUIT_CCS811_H 2 #define LIB_ADAFRUIT_CCS811_H 3 4 #if (ARDUINO >= 100) 5 #include "Arduino.h" 6 #else 7 #include "WProgram.h" 8 #endif 9 10 #include <Wire.h> 11 12 /*========================================================================= 13 I2C ADDRESS/BITS 14 -----------------------------------------------------------------------*/ 15 #define CCS811_ADDRESS (0x5A) 16 /*=========================================================================*/ 17 18 /*========================================================================= 19 REGISTERS 20 -----------------------------------------------------------------------*/ 21 enum { 22 CCS811_STATUS = 0x00, 23 CCS811_MEAS_MODE = 0x01, 24 CCS811_ALG_RESULT_DATA = 0x02, 25 CCS811_RAW_DATA = 0x03, 26 CCS811_ENV_DATA = 0x05, 27 CCS811_NTC = 0x06, 28 CCS811_THRESHOLDS = 0x10, 29 CCS811_BASELINE = 0x11, 30 CCS811_HW_ID = 0x20, 31 CCS811_HW_VERSION = 0x21, 32 CCS811_FW_BOOT_VERSION = 0x23, 33 CCS811_FW_APP_VERSION = 0x24, 34 CCS811_ERROR_ID = 0xE0, 35 CCS811_SW_RESET = 0xFF, 36 }; 37 38 // bootloader registers 39 enum { 40 CCS811_BOOTLOADER_APP_ERASE = 0xF1, 41 CCS811_BOOTLOADER_APP_DATA = 0xF2, 42 CCS811_BOOTLOADER_APP_VERIFY = 0xF3, 43 CCS811_BOOTLOADER_APP_START = 0xF4 44 }; 45 46 enum { 47 CCS811_DRIVE_MODE_IDLE = 0x00, 48 CCS811_DRIVE_MODE_1SEC = 0x01, 49 CCS811_DRIVE_MODE_10SEC = 0x02, 50 CCS811_DRIVE_MODE_60SEC = 0x03, 51 CCS811_DRIVE_MODE_250MS = 0x04, 52 }; 53 54 /*=========================================================================*/ 55 56 #define CCS811_HW_ID_CODE 0x81 57 58 #define CCS811_REF_RESISTOR 100000 59 60 /**************************************************************************/ 61 /*! 62 @brief Class that stores state and functions for interacting with CCS811 63 gas sensor chips 64 */ 65 /**************************************************************************/ 66 class Adafruit_CCS811 { 67 public: 68 // constructors 69 Adafruit_CCS811(void){}; 70 ~Adafruit_CCS811(void){}; 71 72 bool begin(uint8_t addr = CCS811_ADDRESS); 73 74 void setEnvironmentalData(float humidity, float temperature); 75 76 uint16_t getBaseline(); 77 void setBaseline(uint16_t baseline); 78 79 // calculate temperature based on the NTC register 80 double calculateTemperature(); 81 82 void setThresholds(uint16_t low_med, uint16_t med_high, 83 uint8_t hysteresis = 50); 84 85 void SWReset(); 86 87 void setDriveMode(uint8_t mode); 88 void enableInterrupt(); 89 void disableInterrupt(); 90 91 /**************************************************************************/ 92 /*! 93 @brief returns the stored total volatile organic compounds measurement. 94 This does does not read the sensor. To do so, call readData() 95 @returns TVOC measurement as 16 bit integer 96 */ 97 /**************************************************************************/ 98 uint16_t getTVOC() { return _TVOC; } 99 100 /**************************************************************************/ 101 /*! 102 @brief returns the stored estimated carbon dioxide measurement. This does 103 does not read the sensor. To do so, call readData() 104 @returns eCO2 measurement as 16 bit integer 105 */ 106 /**************************************************************************/ 107 uint16_t geteCO2() { return _eCO2; } 108 109 /**************************************************************************/ 110 /*! 111 @brief returns the "Current Selected" in uA. 112 This does does not read the sensor. To do so, call readData() 113 @returns "Current Selected" in uA as 16 bit integer 114 */ 115 /**************************************************************************/ 116 uint16_t getCurrentSelected() { return _currentSelected; } 117 118 /**************************************************************************/ 119 /*! 120 @brief returns the raw ADC reading. This does 121 does not read the sensor. To do so, call readData() 122 @returns raw ADC reading as 16 bit integer 123 */ 124 /**************************************************************************/ 125 uint16_t getRawADCreading() { return _rawADCreading; } 126 127 /**************************************************************************/ 128 /*! 129 @brief set the temperature compensation offset for the device. This is 130 needed to offset errors in NTC measurements. 131 @param offset the offset to be added to temperature measurements. 132 */ 133 /**************************************************************************/ 134 void setTempOffset(float offset) { _tempOffset = offset; } 135 136 // check if data is available to be read 137 bool available(); 138 uint8_t readData(); 139 140 bool checkError(); 141 142 private: 143 uint8_t _i2caddr; 144 float _tempOffset; 145 146 uint16_t _TVOC; 147 uint16_t _eCO2; 148 149 uint16_t _currentSelected; 150 uint16_t _rawADCreading; 151 152 void write8(byte reg, byte value); 153 void write16(byte reg, uint16_t value); 154 uint8_t read8(byte reg); 155 156 void read(uint8_t reg, uint8_t *buf, uint8_t num); 157 void write(uint8_t reg, uint8_t *buf, uint8_t num); 158 void _i2c_init(); 159 160 /*========================================================================= 161 REGISTER BITFIELDS 162 -----------------------------------------------------------------------*/ 163 // The status register 164 struct status { 165 166 /* 0: no error 167 * 1: error has occurred 168 */ 169 uint8_t ERROR : 1; 170 171 // reserved : 2 172 173 /* 0: no samples are ready 174 * 1: samples are ready 175 */ 176 uint8_t DATA_READY : 1; 177 uint8_t APP_VALID : 1; 178 179 // reserved : 2 180 181 /* 0: boot mode, new firmware can be loaded 182 * 1: application mode, can take measurements 183 */ 184 uint8_t FW_MODE : 1; 185 186 void set(uint8_t data) { 187 ERROR = data & 0x01; 188 DATA_READY = (data >> 3) & 0x01; 189 APP_VALID = (data >> 4) & 0x01; 190 FW_MODE = (data >> 7) & 0x01; 191 } 192 }; 193 status _status; 194 195 // measurement and conditions register 196 struct meas_mode { 197 // reserved : 2 198 199 /* 0: interrupt mode operates normally 200 * 1: Interrupt mode (if enabled) only asserts the nINT signal (driven low) if 201 the new ALG_RESULT_DATA crosses one of the thresholds set in the THRESHOLDS 202 register by more than the hysteresis value (also in the THRESHOLDS register) 203 */ 204 uint8_t INT_THRESH : 1; 205 206 /* 0: int disabled 207 * 1: The nINT signal is asserted (driven low) when a new sample is ready in 208 ALG_RESULT_DATA. The nINT signal will stop being driven low 209 when ALG_RESULT_DATA is read on the I²C interface. 210 */ 211 uint8_t INT_DATARDY : 1; 212 213 uint8_t DRIVE_MODE : 3; 214 215 uint8_t get() { 216 return (INT_THRESH << 2) | (INT_DATARDY << 3) | (DRIVE_MODE << 4); 217 } 218 }; 219 meas_mode _meas_mode; 220 221 struct error_id { 222 /* The CCS811 received an I²C write request addressed to this station but 223 with invalid register address ID */ 224 uint8_t WRITE_REG_INVALID : 1; 225 226 /* The CCS811 received an I²C read request to a mailbox ID that is invalid 227 */ 228 uint8_t READ_REG_INVALID : 1; 229 230 /* The CCS811 received an I²C request to write an unsupported mode to 231 MEAS_MODE */ 232 uint8_t MEASMODE_INVALID : 1; 233 234 /* The sensor resistance measurement has reached or exceeded the maximum 235 range */ 236 uint8_t MAX_RESISTANCE : 1; 237 238 /* The Heater current in the CCS811 is not in range */ 239 uint8_t HEATER_FAULT : 1; 240 241 /* The Heater voltage is not being applied correctly */ 242 uint8_t HEATER_SUPPLY : 1; 243 244 void set(uint8_t data) { 245 WRITE_REG_INVALID = data & 0x01; 246 READ_REG_INVALID = (data & 0x02) >> 1; 247 MEASMODE_INVALID = (data & 0x04) >> 2; 248 MAX_RESISTANCE = (data & 0x08) >> 3; 249 HEATER_FAULT = (data & 0x10) >> 4; 250 HEATER_SUPPLY = (data & 0x20) >> 5; 251 } 252 }; 253 error_id _error_id; 254 255 /*=========================================================================*/ 256 }; 257 258 #endif