Tasmota/lib/lib_i2c/ScioSense_ENS210/src/ScioSense_ENS210.h

150 lines
7.4 KiB
C++

/*
ScioSense_ENS210.h - Library for the ENS210 relative humidity and temperature sensor with I2C interface from ScioSense
2020 Apr 06 v3 Chrsitoph Friese Changed nomenclature to ScioSense as product shifted from ams
2018 Aug 28 v2 Christoph Friese Adjusted I2C communication
2017 Aug 01 v1 Maarten Pennings Created
*/
#ifndef __SCIOSENSE_ENS210_H_
#define __SCIOSENSE_ENS210_H_
#define ENS210_DISABLE_DEBUG
#define ENS210_DISABLE_ENHANCED_FEATURES
#if (ARDUINO >= 100)
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#include <Wire.h>
#define ENS210_I2CADDR 0x43 //ADDR low
// Chip constants
#define ENS210_PARTID 0x0210 // The expected part id of the ENS210
#define ENS210_BOOTING 2 // Booting time in ms (also after reset, or going to high power)
#define ENS210_THCONV_SINGLE_MS 130 // Conversion time in ms for single shot T/H measurement
#define ENS210_THCONV_CONT_MS 238 // Conversion time in ms for continuous T/H measurement
// Addresses of the ENS210 registers
#define ENS210_REG_PART_ID 0x00
#define ENS210_REG_REV 0x02
#define ENS210_REG_UID 0x04
#define ENS210_REG_SYS_CTRL 0x10
#define ENS210_REG_SYS_STAT 0x11
#define ENS210_REG_SENS_RUN 0x21
#define ENS210_REG_SENS_START 0x22
#define ENS210_REG_SENS_STOP 0x23
#define ENS210_REG_SENS_STAT 0x24
#define ENS210_REG_T_VAL 0x30
#define ENS210_REG_H_VAL 0x33
// Division macro (used in conversion functions), implementing integer division with rounding.
// It supports both positive and negative dividends (n), but ONLY positive divisors (d).
//#define IDIV(n,d) ((n)>0 ? ((n)+(d)/2)/(d) : ((n)-(d)/2)/(d))
// 7654 3210
// Polynomial 0b 1000 1001 ~ x^7+x^3+x^0
// 0x 8 9
#define CRC7WIDTH 7 // A 7 bits CRC has polynomial of 7th order, which has 8 terms
#define CRC7POLY 0x89 // The 8 coefficients of the polynomial
#define CRC7IVEC 0x7F // Initial vector has all 7 bits high
// Payload data
#define DATA7WIDTH 17
#define DATA7MASK ((1UL<<DATA7WIDTH)-1) // 0b 0 1111 1111 1111 1111
#define DATA7MSB (1UL<<(DATA7WIDTH-1)) // 0b 1 0000 0000 0000 0000
// Measurement status as output by `measure()` and `extract()`.
// Note that the ENS210 provides a "value" (`t_val` or `h_val` each 24 bit).
// A "value" consists of a payload (17 bit) and a CRC (7 bit) over that payload.
// The payload consists of a valid flag (1 bit) and the actual measurement "data" (`t_data` or `h_data`, 16 bit)
#define ENS210_STATUS_I2CERROR 4 // There was an I2C communication error, `read`ing the value.
#define ENS210_STATUS_CRCERROR 3 // The value was read, but the CRC over the payload (valid and data) does not match.
#define ENS210_STATUS_INVALID 2 // The value was read, the CRC matches, but the data is invalid (e.g. the measurement was not yet finished).
#define ENS210_STATUS_OK 1 // The value was read, the CRC matches, and data is valid.
class ScioSense_ENS210 {
public:
ScioSense_ENS210(uint8_t slaveaddr = ENS210_I2CADDR);
#ifndef ENS210_DISABLE_ENHANCED_FEATURES
void setI2C(uint8_t sda, uint8_t scl);
void changeAddr(uint8_t oldAddr, uint8_t newAddr);
#endif
bool begin(bool debug=false); // init i2c interface, get partID und uID. Returns false on I2C problems or wrong PART_ID.
bool setSingleMode(bool enable); // false for continuous mode / true for single shot measurement. Returns false on I2C problems.
bool available() { return this->_available; }
uint16_t getPartID() { return this->_partID; }
uint16_t getRev() { return this->_rev; }
uint32_t getHighUID(bool high) { uint32_t result = high ? this->_uIDhi : this->_uIDlo; return result; }
void measure(); // perfrom measurement and stores result in internal variables
#ifndef ENS210_DISABLE_ENHANCED_FEATURES
float getTempKelvin (); // Converts and returns data (from `measure`) in Kelvin
float getTempFahrenheit (); // Converts and returns data (from `measure`) in Fahrenheit
#endif
float getTempCelsius (); // Converts and returns data (from `measure`) in Celsius
float getHumidityPercent(); // Converts and returns data (from `measure`) in %RH
#ifndef ENS210_DISABLE_ENHANCED_FEATURES
float getAbsoluteHumidityPercent(); // Converts and returns data (from `measure`) in %aH
#endif
char getStatusT() { return this->_t_status; } // Converts a status (ENS210_STATUS_XXX) to a human readable string.
uint32_t getDataT() { return this->_t_data; }
char getStatusH() { return this->_h_status; } // Converts a status (ENS210_STATUS_XXX) to a human readable string.
uint32_t getDataH() { return this->_h_data; }
#ifndef ENS210_DISABLE_ENHANCED_FEATURES
static const char * status_str( int status ); // Converts a status (ENS210_STATUS_XXX) to a human readable string.
#endif
// Optionally set a solder `correction` (units: 1/64K, default from `begin` is 0).
// See "Effect of Soldering on Temperature Readout" in "Design-Guidelines" from
// https://download.ams.com/ENVIRONMENTAL-SENSORS/ENS210/Documentation
#ifndef ENS210_DISABLE_ENHANCED_FEATURES
void correction_set(int correction=50*64/1000); // Sets the solder correction (default is 50mK) - only used by the `toXxx()` functions.
int correction_get() {return this->_soldercorrection;} // Gets the solder correction.
#endif
private:
#ifndef ENS210_DISABLE_DEBUG
bool debugENS210 = false;
#endif
bool reset(void); // Sends a reset to the ENS210. Returns false on I2C problems.
bool lowpower(bool enable); // Sets ENS210 to low (true) or high (false) power. Returns false on I2C problems.
bool getversion(); // Reads PART_ID and UID of ENS210. Returns false on I2C problems.
bool readValue(); // Reads measurement data from the ENS210. Returns false on I2C problems.
bool _available = false; // ENS210 available
uint16_t _partID; // Part ID of ENS210, should be 0x210
uint16_t _rev; // Revision 0 MRA2.6 / 1 MRA2.12
uint64_t _uID; // Unique ID of this specific ENS210
uint32_t _uIDhi; // First 32bit of unique ID of this specific ENS210
uint32_t _uIDlo; // Second 32bit of unique ID of this specific ENS210
bool _singleMode = true; // Measurement mode: true single shot / false continuous
uint32_t _t_data;
uint8_t _t_status;
uint32_t _h_data;
uint8_t _h_status;
uint8_t _slaveaddress = 0x43; // Slave address of ENS210
uint8_t _soldercorrection; // Correction due to soldering (in 1/64K); subtracted from `t_data` by conversion functions.
uint8_t _sdaPin = 0;
uint8_t _sclPin = 0;
/****************************************************************************/
/* General functions */
/****************************************************************************/
uint8_t write8(uint8_t addr, byte reg, byte value);
uint8_t read8(uint8_t addr, byte reg);
uint8_t read(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t num);
uint8_t write(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t num);
void _i2c_init();
};
#endif