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