M5Atom_airqa/ccs811.h

102 lines
7.8 KiB
C++

/*
ccs811.h - Library for the CCS811 digital gas sensor for monitoring indoor air quality from ams.
2019 jan 22 v10 Maarten Pennings Added F() on all strings, added get/set_baseline()
2019 jan 15 v9 Maarten Pennings Flash&i2cwrite now use const array
2018 dec 06 v8 Maarten Pennings Added firmware flash routine
2018 Dec 04 v7 Maarten Pennings Added support for older CCS811's (fw 1100)
2018 Nov 11 v6 Maarten Pennings uint16 -> uint16_t
2018 Nov 02 v5 Maarten Pennings Added clearing of ERROR_ID
2018 Oct 23 v4 Maarten Pennings Added envdata/i2cdelay
2018 Oct 21 v3 Maarten Pennings Added hw-version
2018 Oct 21 v2 Maarten Pennings Simplified I2C, added version mngt
2017 Dec 11 v1 Maarten Pennings Created
*/
#ifndef _CCS811_H_
#define _CCS811_H_
// To help diagnose problems, the begin() and flash() functions print diagnostic messages to Serial.
// If you do not want that, make the PRINT macros in ccs811.cpp empty.
#include <stdint.h>
// Version of this CCS811 driver
#define CCS811_VERSION 10
// I2C slave address for ADDR 0 respectively 1
#define CCS811_SLAVEADDR_0 0x5A
#define CCS811_SLAVEADDR_1 0x5B
// The values for mode in ccs811_start()
#define CCS811_MODE_IDLE 0
#define CCS811_MODE_1SEC 1
#define CCS811_MODE_10SEC 2
#define CCS811_MODE_60SEC 3
// The flags for errstat in ccs811_read()
// ERRSTAT is a merge of two hardware registers: ERROR_ID (bits 15-8) and STATUS (bits 7-0)
// Also bit 1 (which is always 0 in hardware) is set to 1 when an I2C read error occurs
#define CCS811_ERRSTAT_ERROR 0x0001 // There is an error, the ERROR_ID register (0xE0) contains the error source
#define CCS811_ERRSTAT_I2CFAIL 0x0002 // Bit flag added by software: I2C transaction error
#define CCS811_ERRSTAT_DATA_READY 0x0008 // A new data sample is ready in ALG_RESULT_DATA
#define CCS811_ERRSTAT_APP_VALID 0x0010 // Valid application firmware loaded
#define CCS811_ERRSTAT_FW_MODE 0x0080 // Firmware is in application mode (not boot mode)
#define CCS811_ERRSTAT_WRITE_REG_INVALID 0x0100 // The CCS811 received an I²C write request addressed to this station but with invalid register address ID
#define CCS811_ERRSTAT_READ_REG_INVALID 0x0200 // The CCS811 received an I²C read request to a mailbox ID that is invalid
#define CCS811_ERRSTAT_MEASMODE_INVALID 0x0400 // The CCS811 received an I²C request to write an unsupported mode to MEAS_MODE
#define CCS811_ERRSTAT_MAX_RESISTANCE 0x0800 // The sensor resistance measurement has reached or exceeded the maximum range
#define CCS811_ERRSTAT_HEATER_FAULT 0x1000 // The heater current in the CCS811 is not in range
#define CCS811_ERRSTAT_HEATER_SUPPLY 0x2000 // The heater voltage is not being applied correctly
// These flags should not be set. They flag errors.
#define CCS811_ERRSTAT_HWERRORS ( CCS811_ERRSTAT_ERROR | CCS811_ERRSTAT_WRITE_REG_INVALID | CCS811_ERRSTAT_READ_REG_INVALID | CCS811_ERRSTAT_MEASMODE_INVALID | CCS811_ERRSTAT_MAX_RESISTANCE | CCS811_ERRSTAT_HEATER_FAULT | CCS811_ERRSTAT_HEATER_SUPPLY )
#define CCS811_ERRSTAT_ERRORS ( CCS811_ERRSTAT_I2CFAIL | CCS811_ERRSTAT_HWERRORS )
// These flags should normally be set - after a measurement. They flag data available (and valid app running).
#define CCS811_ERRSTAT_OK ( CCS811_ERRSTAT_DATA_READY | CCS811_ERRSTAT_APP_VALID | CCS811_ERRSTAT_FW_MODE )
// These flags could be set after a measurement. They flag data is not yet available (and valid app running).
#define CCS811_ERRSTAT_OK_NODATA ( CCS811_ERRSTAT_APP_VALID | CCS811_ERRSTAT_FW_MODE )
class CCS811 {
public: // Main interface
CCS811(int nwake=-1, int slaveaddr=CCS811_SLAVEADDR_0); // Pin number connected to nWAKE (nWAKE can also be bound to GND, then pass -1), slave address (5A or 5B)
bool begin( void ); // Reset the CCS811, switch to app mode and check HW_ID. Returns false on problems.
bool start( int mode ); // Switched CCS811 to `mode`, use constants CCS811_MODE_XXX. Returns false on I2C problems.
void read( uint16_t*eco2, uint16_t*etvoc, uint16_t*errstat,uint16_t*raw); // Get measurement results from the CCS811 (all args may be NULL), check status via errstat, e.g. ccs811_errstat(errstat)
const char * errstat_str(uint16_t errstat); // Returns a string version of an errstat. Note, each call, this string is updated.
public: // Extra interface
int hardware_version(void); // Gets version of the CCS811 hardware (returns -1 on I2C failure)
int bootloader_version(void); // Gets version of the CCS811 bootloader (returns -1 on I2C failure)
int application_version(void); // Gets version of the CCS811 application (returns -1 on I2C failure)
int get_errorid(void); // Gets the ERROR_ID [same as 'err' part of 'errstat' in 'read'] (returns -1 on I2C failure)
bool set_envdata(uint16_t t, uint16_t h); // Writes t and h to ENV_DATA (see datasheet for format). Returns false on I2C problems.
bool set_envdata210(uint16_t t, uint16_t h); // Writes t and h (in ENS210 format) to ENV_DATA. Returns false on I2C problems.
bool get_baseline(uint16_t *baseline); // Reads (encoded) baseline from BASELINE. Returns false on I2C problems. Get it, just before power down (but only when sensor was on at least 20min) - see CCS811_AN000370
bool set_baseline(uint16_t baseline); // Writes (encoded) baseline to BASELINE. Returns false on I2C problems. Set it, after power up (and after 20min)
bool flash(const uint8_t * image, int size); // Flashes the firmware of the CCS811 with size bytes from image - image _must_ be in PROGMEM
public: // Advanced interface: i2cdelay
void set_i2cdelay(int us); // Delay before a repeated start - needed for e.g. ESP8266 because it doesn't handle I2C clock stretch correctly
int get_i2cdelay(void); // Get current delay
protected: // Helper interface: nwake pin
void wake_init(void); // Initialize nwake pin
void wake_up(void); // Wake up CCS811, i.e. pull nwake pin low
void wake_down(void); // CCS811 back to sleep, i.e. pull nwake pin high
protected: // Helper interface: i2c wrapper
bool i2cwrite(int regaddr, int count, const uint8_t * buf); // Writes `count` from `buf` to register at address `regaddr` in the CCS811. Returns false on I2C problems.
bool i2cread (int regaddr, int count, uint8_t * buf); // Reads 'count` bytes from register at address `regaddr`, and stores them in `buf`. Returns false on I2C problems.
private:
int _nwake; // Pin number for nWAKE pin (or -1)
int _slaveaddr; // Slave address of the CCS811
int _i2cdelay_us; // Delay in us just before an I2C repeated start condition
int _appversion; // Version of the app firmware inside the CCS811 (for workarounds)
};
#endif