Adafruit_CCS811.h 7.1 KB

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