simple CCS811 driver
Dependencies: AMS_ENS210_temp_humid_sensor
Dependents: TBSense2_Sensor_Demo
Fork of AMS_CCS811_gas_sensor by
AMS_CCS811.h
00001 /** 00002 * @author Marcus Lee 00003 * 00004 * @section DESCRIPTION 00005 * A library for the AMS CCS811 digital gas sensor. 00006 * 00007 */ 00008 #ifndef AMS_CCS811_H 00009 #define AMS_CCS811_H 00010 00011 #include "mbed.h" 00012 #include "AMS_ENS210.h" 00013 00014 /* Library defaults */ 00015 #define CONFIG_OP_MODE TEN_SECOND // Every 10 seconds 00016 #define CONFIG_INTR 0 // Interupt off 00017 #define CONFIG_ADDR_DIR 0 // ADDR n_wake_pin pulled low 00018 #define CONFIG_ENS210_POLL 3000 // ENS210 is polled every 3 seconds 00019 00020 /* Library Constants */ 00021 #define CCS811_SLAVE_ADDR_RAW_H 0x5B 00022 #define CCS811_SLAVE_ADDR_RAW_L 0x5A 00023 #define CCS811_SLAVE_ADDR_RAW _slave_addr 00024 #define CCS811_SLAVE_ADDR CCS811_SLAVE_ADDR_RAW << 1 00025 #define CCS811_SLAVE_ADDR_W CCS811_SLAVE_ADDR 00026 #define CCS811_SLAVE_ADDR_R CCS811_SLAVE_ADDR | 1 00027 00028 #define MEAS_MODE 0x01 00029 #define STATUS 0x00 00030 00031 #define ALG_RESULT_DATA 0x02 00032 #define RAW_DATA 0x03 00033 #define ENV_DATA 0x05 00034 #define ERROR_ID 0xE0 00035 00036 #define HW_ID 0x20 00037 #define HW_VERSION 0x21 00038 #define FW_BOOT_VERSION 0x23 00039 #define FW_APP_VERSION 0x24 00040 #define FW_ERASE 0xF1 00041 #define FW_FLASH 0xF2 00042 #define FW_VERIFY 0xF3 00043 #define APP_START 0xF4 00044 00045 #define CCS811_T_AWAKE 55 // us - time taken for sensor I2C to become active 00046 #define CCS811_T_DWAKE 25 // us - time taken for sensor I2C to become inactive 00047 00048 #define CCS811_MAX_HUMID 127.998046875 // maxmium value that can be represented in the register 00049 #define CCS811_MAX_TEMP 102.998046875 // maxmium value that can be represented in the register 00050 00051 /* Error Codes */ 00052 #define CCS811_NO_ERROR "No Error"; 00053 /* Sensor Errors */ 00054 #define CCS811_ERR_NUM 8 00055 #define CCS811_WRITE_REG_INVALID "The CCS811 received an I2C write request addressed to this station but with invalid register address ID" 00056 #define CCS811_READ_REG_INVALID "The CCS811 received an I2C read request to a mailbox ID that is invalid" 00057 #define CCS811_MEASMODE_INVALID "The CCS811 received an I2C request to write an unsupported mode to MEAS_MODE" 00058 #define CCS811_MAX_RESISTANCE "The sensor resistance measurement has reached or exceeded the maximum range" 00059 #define CCS811_HEATER_FAULT "The Heater current in the CCS811 is not in range" 00060 #define CCS811_HEATER_SUPPLY "The Heater voltage is not being applied correctly" 00061 #define CCS811_RESERVED "Reserved for Future Use" 00062 /* Library Errors */ 00063 #define CCS811_LIB_ERR_NUM 9 00064 #define CCS811_LIB_N_WAKE_ID 0 00065 #define CCS811_LIB_N_WAKE "nWAKE pin not set" 00066 #define CCS811_LIB_I2C_ID 1 00067 #define CCS811_LIB_I2C "I2C interface is NULL" 00068 #define CCS811_LIB_SLAVE_W_ID 2 00069 #define CCS811_LIB_SLAVE_W "Failed to write slave write address" 00070 #define CCS811_LIB_REG_ADDR_ID 3 00071 #define CCS811_LIB_REG_ADDR "Failed to write register address" 00072 #define CCS811_LIB_I2CWRITE_ID 4 00073 #define CCS811_LIB_I2CWRITE "Failed to write byte" 00074 #define CCS811_LIB_SLAVE_R_ID 5 00075 #define CCS811_LIB_SLAVE_R "Failed to write slave read address" 00076 #define CCS811_LIB_INV_MODE_ID 6 00077 #define CCS811_LIB_INV_MODE "Invalid operation mode" 00078 #define CCS811_LIB_ENS210_INIT_ID 7 00079 #define CCS811_LIB_ENS210_INIT "Failed to create new AMS_ENS210 object" 00080 #define CCS811_LIB_ENS210_POLL_ID 7 00081 #define CCS811_LIB_ENS210_POLL "AMS_ENS210 poll error" 00082 00083 #define CCS811_TOTAL_ERR_NUM CCS811_ERR_NUM+CCS811_LIB_ERR_NUM 00084 00085 00086 /** The AMS CCS811 class 00087 */ 00088 class AMS_CCS811 00089 { 00090 public: 00091 /** Sensor operation modes. 00092 * 00093 */ 00094 enum OP_MODES { 00095 IDLE, /**< Measurements disabled */ 00096 SECOND, /**< Measurement every second */ 00097 TEN_SECOND, /**< Measurement every 10 seconds */ 00098 SIXTY_SECOND, /**< Measurement every 60 seconds */ 00099 CONSTANT, /**< Measurement every 250ms - Only raw data available */ 00100 INVALID /**< Invalid bit configuration/Error Occured */ 00101 }; 00102 00103 /** Holds error information. 00104 * 00105 */ 00106 struct ccs811_errors { 00107 int count; /**< Number of total errors */ 00108 int codes[CCS811_TOTAL_ERR_NUM]; /**< Array of active error codes */ 00109 00110 ccs811_errors() : count(0) {} 00111 }; 00112 00113 /** Create an AMS_CCS811 instance 00114 * 00115 * @param i2c The I2C interface to use for communication 00116 * @param n_wake_pin Pin nWAKE is attached to 00117 */ 00118 AMS_CCS811(I2C * i2c, PinName n_wake_pin); 00119 00120 /** Create an AMS_CCS811 instance 00121 * 00122 * @param i2c The I2C interface to use for communication 00123 * @param n_wake_pin Pin nWAKE is attached to 00124 * @param ens210_i2c The I2C interface for an attached AMS_ENS210 00125 */ 00126 AMS_CCS811(I2C * i2c, PinName n_wake_pin, I2C * ens210_i2c); 00127 00128 /** Destroy the AMS_CCS811 instance 00129 */ 00130 ~AMS_CCS811(); 00131 00132 /** Initalise the sensor 00133 * 00134 * @return Intalisation success 00135 */ 00136 bool init(); 00137 00138 /** Overwrite the sensor's firmware 00139 * 00140 * @return upload success 00141 */ 00142 bool flash_firmware(); 00143 00144 /** Set the I2C interface 00145 * 00146 * @param i2c The I2C interface to use for communication 00147 * 00148 */ 00149 void i2c_interface(I2C * i2c); 00150 00151 /** Set the ENS210 I2C interface 00152 * 00153 * @param i2c The I2C interface for an attached AMS_ENS210 00154 * 00155 * @return Success 00156 */ 00157 bool ens210_i2c_interface(I2C * i2c); 00158 00159 /** Set whether the attached AMS_ENS210 is enabled. 00160 * If an I2C interface is not set for the ENS210, calling this method will have no effect. 00161 * 00162 * @param enabled True for enabled, false for disabled 00163 * 00164 * @return enabled True for enabled, false for disabled 00165 */ 00166 bool enable_ens210(bool enable); 00167 00168 /** Get whether the attached AMS_ENS210 is enabled. 00169 * 00170 * @return enabled True for enabled, false for disabled 00171 * 00172 */ 00173 bool ens210_is_enabled(); 00174 00175 /** Set the AMS_ENS210 poll interval 00176 * 00177 * @param poll_ms Poll interval in ms 00178 * 00179 */ 00180 void ens210_poll_interval(int poll_ms); 00181 00182 /** Get the AMS_ENS210 poll interval 00183 * 00184 * @return The poll interval in ms 00185 */ 00186 int ens210_poll_interval(); 00187 00188 /** Get the current firmware mode 00189 * 00190 * @return 1 application mode, 0 for boot mode, -1 for error 00191 */ 00192 int firmware_mode(); 00193 00194 /** Set the operation mode \n 00195 * Notes: \n 1.\ When a sensor operating mode is changed to a new mode with\n 00196 * a lower sample rate (e.g.\ from SECOND to SIXTY_SECOND), it should be\n 00197 * placed in IDLE for at least 10 minutes before enabling the new mode.\ \n 00198 * When a sensor operating mode is changed to a new mode with a higher\n 00199 * sample rate (e.g.\ from SIXTY_SECOND to SECOND), there is no requirement\n 00200 * to wait before enabling the new mode.\ \n 00201 * 2.\ If this method fails, the state of the config register cannot be guaranteed.\ \n 00202 * Check errors and ensure all config settings are as expected. 00203 * 00204 * @param mode OP_MODES mode to set 00205 * 00206 * @return Write success 00207 */ 00208 bool mode(OP_MODES mode); 00209 00210 /** Get the current power mode 00211 * 00212 * @return The current OP_MODES mode 00213 */ 00214 AMS_CCS811::OP_MODES mode(); 00215 00216 /** Set the ADDR mode \n 00217 * 00218 * @param high True sets to high, false to low 00219 * 00220 * @return Write success 00221 */ 00222 bool addr_mode(bool high); 00223 00224 /** Get the the ADDR mode 00225 * 00226 * @return The current ADDR mode, true for high, false for low 00227 */ 00228 bool addr_mode(); 00229 00230 /** Set the ADDR pin 00231 * 00232 * @param pin Pin ADDR is attached to 00233 * 00234 * @return Write success 00235 */ 00236 bool addr_pin(PinName pin); 00237 00238 /** Get the the ADDR pin 00239 * 00240 * @return The addr pin 00241 */ 00242 PinName addr_pin(); 00243 00244 /** Set the nWAKE pin 00245 * 00246 * @param pin Pin nWAKE is attached to 00247 * 00248 * @return Write success 00249 */ 00250 bool n_wake_pin(PinName pin); 00251 00252 /** Get the the nWAKE pin 00253 * 00254 * @return The nWAKE pin 00255 */ 00256 PinName n_wake_pin(); 00257 00258 /** Set the relative humidity (%) and temperature (C).\ \n 00259 * Use when AMS ENS210 is not linked.\ \n 00260 * Humidity values are clipped between 0 and CCS811_MAX_HUMID.\ \n 00261 * Temperature values are clipped between -25 and CCS811_MAX_TEMP. 00262 * 00263 * @return Write success 00264 */ 00265 bool env_data(float humid, float temp); 00266 00267 /** Get the sensor collection state 00268 * Use when interrupts are disabled. 00269 * 00270 * @return Current collection state, 1 for new data ready, 0 for data not ready and -1 for error 00271 */ 00272 int has_new_data(); 00273 00274 /** Get the most recent CO2 measurement.\ \n 00275 * Must call has_new_data() first when when interupts are disabled otherwise the same data will be returned 00276 * 00277 * @return Most recent eCO2 measurement in ppm 00278 */ 00279 uint16_t co2_read(); 00280 00281 /** Get the most recent TVOC measurement.\ \n 00282 * Must call has_new_data() first when when interupts are disabled otherwise the same data will be returned 00283 * 00284 * @return Most recent TVOC measurement in ppb 00285 */ 00286 uint16_t tvoc_read(); 00287 00288 /** Get the most recent RAW data.\ \n 00289 * Must call has_new_data() first when NOT in CONSTANT mode and interupts are disabled otherwise the same data will be returned.\ \n 00290 * When in CONSTANT mode only this read method will return anything other than 0 or NULL.\ If 0 is returned, check for errors. 00291 * 00292 * @return Most recent RAW data 00293 */ 00294 uint16_t raw_read(); 00295 00296 /** Get the most recent Tempurature(C) measurement from the ENS210 (if attached and enabled).\ \n 00297 * Will be at most as old as the ENS210 poll time 00298 * 00299 * @return Most recent Tempurature(C) measurement from the ENS210 00300 */ 00301 float temp_read(); 00302 00303 /** Get the most recent Relative Humidity(%) measurement from the ENS210 (if attached and enabled).\ \n 00304 * Will be at most as old as the ENS210 poll time 00305 * 00306 * @return Most recent Relative Humidity(%) measurement from the ENS210 00307 */ 00308 float humid_read(); 00309 00310 /** Get current error status 00311 * 00312 * @return True when error has occured, false when no error has occured 00313 */ 00314 bool error_status(); 00315 00316 /** Get the latest errors. 00317 * 00318 * @return Latest errors. 00319 */ 00320 ccs811_errors errors(); 00321 00322 /** Get the error string. 00323 * 00324 * @param err_code Error code to be translated 00325 * 00326 * @return Error String. 00327 */ 00328 const char * error_string(int err_code); 00329 00330 /** Attach a function to be called when data is ready. 00331 * Calling this method enables interupts 00332 * 00333 * @param func_ptr A pointer to the function to be called 00334 * @param pin Pin attached to nINT 00335 * 00336 * @return Attach success 00337 */ 00338 bool attach(void (*func_ptr)(void), PinName pin) { 00339 _isr_data_fp.attach(func_ptr); 00340 interrupt_pin(pin); 00341 return enable_interupt(true); 00342 } 00343 00344 /** Attach a member function to be called when data is ready. 00345 * Calling this method enables interupts 00346 * 00347 * @param type_ptr A pointer to the instance of the class 00348 * @param mem_ptr A pointer to the member function 00349 * @param pin Pin attached to nINT 00350 * 00351 * @return Attach success 00352 */ 00353 template<typename T> 00354 bool attach(T *type_ptr, void (T::*mem_ptr)(void), PinName pin) { 00355 _isr_data_fp.attach(callback(type_ptr, mem_ptr)); 00356 interrupt_pin(pin); 00357 return enable_interupt(true); 00358 } 00359 00360 /** Set whether the data ready interupt is enabled.\ \n 00361 * Note: If this method fails, the state of the config register cannot be guaranteed.\ \n 00362 * Check errors and ensure all config settings are as expected. 00363 * 00364 * @param enabled True for enabled, false for disabled 00365 * 00366 * @return Write success 00367 */ 00368 bool enable_interupt(bool enable); 00369 00370 /** Get whether the data ready interupt is enabled. 00371 * 00372 * 00373 * @return 1 for enabled, 0 for disabled, -1 for error 00374 */ 00375 int interupt_enabled(); 00376 00377 /** Set the nINT pin 00378 * 00379 * @param pin Pin nINT is attached to 00380 * 00381 * @return Write success 00382 */ 00383 bool interrupt_pin(PinName pin); 00384 00385 /** Get the the nINT pin 00386 * 00387 * @return The nINT pin 00388 */ 00389 PinName interrupt_pin(); 00390 00391 00392 00393 00394 private: 00395 I2C* _i2c; 00396 00397 bool _addr_dir; 00398 int _slave_addr; 00399 void update_slave_addr(); 00400 00401 AMS_ENS210 *_ens210; 00402 bool _ens210_enabled; 00403 int _ens210_poll_split; 00404 void update_ens210_timer(); 00405 Ticker _ens210_poll_t; 00406 void ens210_isr(); 00407 float temp_reading; 00408 float humid_reading; 00409 00410 float fractions[9]; 00411 void _init_fractions(); 00412 void float_to_short(float in, char * output); 00413 00414 OP_MODES _mode; 00415 00416 void set_defaults(); 00417 00418 bool _errors[CCS811_LIB_ERR_NUM]; 00419 int _error_count; 00420 char _error_strings[CCS811_TOTAL_ERR_NUM][255]; 00421 void _init_errors(); 00422 void clear_errors(); 00423 void new_error(int error_id); 00424 00425 DigitalOut *_n_wake_out; 00426 DigitalOut *_addr_out; 00427 00428 char _alg_result_data[8]; 00429 00430 FunctionPointer _isr_data_fp; 00431 bool _int_data_enabled; 00432 InterruptIn *_int_data; 00433 void _isr_data(); 00434 00435 bool write_config(); 00436 00437 struct read_byte_result { 00438 bool success; 00439 uint8_t byte; 00440 read_byte_result() : success(false), byte(0) {} 00441 }; 00442 read_byte_result read_config(); 00443 read_byte_result read_status(); 00444 00445 bool boot_app_start(); 00446 00447 int i2c_read(char reg_addr, char* output, int len); 00448 int i2c_write(char reg_addr, char* input, int len); 00449 00450 }; 00451 00452 00453 #endif /* AMS_CCS811_H */
Generated on Thu Jul 14 2022 16:17:55 by 1.7.2