Newer
Older
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
#ifndef _CCS811_H
#define _CCS811_H
#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#include <Wire.h>
/*I2C ADDRESS*/
#define CCS811_I2C_ADDRESS1 0x5A
#define CCS811_I2C_ADDRESS2 0x5B
#define CCS811_REG_STATUS 0x00
#define CCS811_REG_MEAS_MODE 0x01
#define CCS811_REG_ALG_RESULT_DATA 0x02
#define CCS811_REG_RAW_DATA 0x03
#define CCS811_REG_ENV_DATA 0x05
#define CCS811_REG_NTC 0x06
#define CCS811_REG_THRESHOLDS 0x10
#define CCS811_REG_BASELINE 0x11
#define CCS811_REG_HW_ID 0x20
#define CCS811_REG_HW_VERSION 0x21
#define CCS811_REG_FW_BOOT_VERSION 0x23
#define CCS811_REG_FW_APP_VERSION 0x24
#define CCS811_REG_INTERNAL_STATE 0xA0
#define CCS811_REG_ERROR_ID 0xE0
#define CCS811_REG_SW_RESET 0xFF
#define CCS811_BOOTLOADER_APP_ERASE 0xF1
#define CCS811_BOOTLOADER_APP_DATA 0xF2
#define CCS811_BOOTLOADER_APP_VERIFY 0xF3
#define CCS811_BOOTLOADER_APP_START 0xF4
#define CCS811_HW_ID 0x81
//Open the macro to see the detailed program execution process.
//#define ENABLE_DBG
#ifdef ENABLE_DBG
#define DBG(...) {Serial.print("[");Serial.print(__FUNCTION__); Serial.print("(): "); Serial.print(__LINE__); Serial.print(" ] "); Serial.println(__VA_ARGS__);}
#else
#define DBG(...)
#endif
class CCS811
{
public:
#define ERR_OK 0 //OK
#define ERR_DATA_BUS -1 //error in data bus
#define ERR_IC_VERSION -2 //chip version mismatch
uint8_t _deviceAddr;
typedef enum{
eMode0, //Idle (Measurements are disabled in this mode)
eMode1, //Constant power mode, IAQ measurement every second
eMode2, //Pulse heating mode IAQ measurement every 10 seconds
eMode3, //Low power pulse heating mode IAQ measurement every 60 seconds
eMode4 //Constant power mode, sensor measurement every 250ms 1xx: Reserved modes (For future use)
}eDRIVE_MODE_t;
typedef enum{
eClosed, //Idle (Measurements are disabled in this mode)
eCycle_1s, //Constant power mode, IAQ measurement every second
eCycle_10s, //Pulse heating mode IAQ measurement every 10 seconds
eCycle_60s, //Low power pulse heating mode IAQ measurement every 60 seconds
eCycle_250ms //Constant power mode, sensor measurement every 250ms 1xx: Reserved modes (For future use)
}eCycle_t;
/**
* @brief Constructor
* @param Input in Wire address
*/
CCS811(TwoWire *pWire = &Wire, uint8_t deviceAddr = 0x5A){_pWire = pWire; _deviceAddr = deviceAddr;};
/**
* @brief Constructor
* @return Return 0 if initialization succeeds, otherwise return non-zero.
*/
int begin();
/**
* @brief Judge if there is data to read
* @return Return 1 if there is, otherwise return 0.
*/
bool checkDataReady();
/**
* @brief Reset sensor, clear all configured data.
*/
void softReset(),
/**
* @brief Set environment parameter
* @param temperature Set temperature value, unit: centigrade, range (-40~85℃)
* @param humidity Set humidity value, unit: RH, range (0~100)
*/
setInTempHum(float temperature, float humidity),
/**
* @brief Measurement parameter configuration
* @param thresh:0 for Interrupt mode operates normally; 1 for interrupt mode only asserts the nINT signal (driven low) if the new
* @param interrupt:0 for Interrupt generation is disabled; 1 for the nINT signal is asserted (driven low) when a new sample is ready in
* @param mode:in typedef enum eDRIVE_MODE_t
*/
setMeasurementMode(uint8_t thresh, uint8_t interrupt, eDRIVE_MODE_t mode),
/**
* @brief Measurement parameter configuration
* @param mode:in typedef enum eDRIVE_MODE_t
*/
setMeasCycle(eCycle_t cycle),
/**
* @brief Set interrupt thresholds
* @param lowToMed: interrupt triggered value in range low to middle
* @param medToHigh: interrupt triggered value in range middle to high
*/
setThresholds(uint16_t lowToMed, uint16_t medToHigh);
/**
* @brief Get current configured parameter
* @return configuration code, needs to be converted into binary code to analyze
* The 2nd: Interrupt mode (if enabled) operates normally,1: Interrupt mode (if enabled) only asserts the nINT signal (driven low) if the new
* The 3rd: Interrupt generation is disabled,1: The nINT signal is asserted (driven low) when a new sample is ready in
* The 4th: 6th: in typedef enum eDRIVE_MODE_t
*/
uint8_t getMeasurementMode();
/**
* @brief Get the current carbon dioxide concentration
* @return current carbon dioxide concentration, unit:ppm
*/
uint16_t getCO2PPM(),
/**
* @brief Get current TVOC concentration
* @return Return current TVOC concentration, unit: ppb
*/
getTVOCPPB();
uint16_t readBaseLine();
void writeBaseLine(uint16_t baseLine);
protected:
typedef struct{
/*
* The CCS811 received an I²C write request addressed to this station but with invalid register address ID
*/
uint8_t sWRITE_REG_INVALID: 1;
/*
* The CCS811 received an I²C read request to a mailbox ID that is invalid
*/
uint8_t sREAD_REG_INVALID: 1;
/*
* The CCS811 received an I²C request to write an unsupported mode to MEAS_MODE
*/
uint8_t sMEASMODE_INVALID: 1;
/*
* The sensor resistance measurement has reached or exceeded the maximum range
*/
uint8_t sMAX_RESISTANCE: 1;
/*
* The The Heater current in the CCS811 is not in range
*/
uint8_t sHEATER_FAULT: 1;
/*
* The Heater voltage is not being applied correctly
*/
uint8_t sHEATER_SUPPLY: 1;
} __attribute__ ((packed))sError_id;
typedef struct{
/*
* 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 sINT_THRESH: 1;
/*
* At the end of each measurement cycle (250ms, 1s, 10s, 60s) a flag is set in the
* STATUS register regardless of the setting of this bit.
*/
uint8_t sINT_DATARDY: 1;
/*
* A new sample is placed in ALG_RESULT_DATA and RAW_DATA registers and the
* DATA_READY bit in the STATUS register is set at the defined measurement interval.
*/
uint8_t sDRIVE_MODE: 3;
} __attribute__ ((packed))sMeas_mode;
typedef struct{
/*
* This bit is cleared by reading ERROR_ID
* It is not sufficient to read the ERROR field of ALG_RESULT_DATA and STATUS
*/
uint8_t sERROR: 1;
/*
* ALG_RESULT_DATA is read on the I²C interface
*/
uint8_t sDATA_READY: 1;
uint8_t sAPP_VALID: 1;
/*
* After issuing a VERIFY command the application software must wait 70ms before
* issuing any transactions to CCS811 over the I²C interface
*/
uint8_t sAPP_VERIFY: 1;
/*
* After issuing the ERASE command the application software must wait 500ms
* before issuing any transactions to the CCS811 over the I2C interface.
*/
uint8_t sAPP_ERASE: 1;
uint8_t sFW_MODE: 1;
} __attribute__ ((packed))sStatus;
void getData(void);
void writeConfig();
virtual void writeReg(uint8_t reg, const void* pBuf, size_t size);
virtual uint8_t readReg(uint8_t reg, const void* pBuf, size_t size);
private:
TwoWire *_pWire;
uint16_t eCO2;
uint16_t eTVOC;
};
#endif