You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

296 lines
9.4 KiB
C++

/***********************
This library was written for the Texas Instruments
HDC100X temperature and humidity sensor.
It has been tested for the HDC1000 and the HDC1008
Buy the HDC1008 breakout board at: https://www.tindie.com/stores/RFgermany
This library is made by Florian Roesner.
Released under GNU GPL v2.0 license.
*************************/
//#include "Arduino.h"
#include "HDC100X.h"
//#include "Wire.h"
//######-----------------------------------------------------------------------
//######-----------------------------------------------------------------------
//PUBLIC:
//######-----------------------------------------------------------------------
//######-----------------------------------------------------------------------
HDC100X::HDC100X(){
ownAddr = HDC100X_ADDR1;
dataReadyPin = -1;
}
//-----------------------------------------------------------------------
HDC100X::HDC100X(uint8_t address){
ownAddr = address;
//dataReadyPin = pin;
}
//-----------------------------------------------------------------------
HDC100X::HDC100X(bool addr0, bool addr1){
// set the two bits the way you set the address jumpers
ownAddr = 0b1000000 |(addr0|(addr1<<1));
//dataReadyPin = pin;
}
//######-----------------------------------------------------------------------
//######-----------------------------------------------------------------------
uint8_t HDC100X::begin(uint8_t mode, uint8_t tempRes, uint8_t humiRes, bool heaterState){
int i;
/* sets the mode and resolution and the state of the heater element. care must be taken, because it will change the temperature reading
** in:
** mode: HDC100X_TEMP_HUMI
** tempRes: HDC100X_11BIT/HDC100X_14BIT
** humiRes: HDC100X_8BIT/HDC100X_11BIT/HDC100X_14BIT
** heaterState: ENABLE/DISABLE
** out:
** high byte of the configuration register
*/
Wire.begin();
// test I2C address
Wire.beginTransmission(ownAddr);
i = Wire.endTransmission();
if(i != 0) // error device not found
{
for(int tries=3; tries!=0; tries--)
{
Wire.beginTransmission(HDC100X_ADDR1);
i = Wire.endTransmission();
if(i == 0)
{
ownAddr = HDC100X_ADDR1;
break;
}
delay(20); // wait 20ms
Wire.beginTransmission(HDC100X_ADDR2);
i = Wire.endTransmission();
if(i == 0)
{
ownAddr = HDC100X_ADDR2;
break;
}
delay(20); // wait 20ms
Wire.beginTransmission(HDC100X_ADDR3);
i = Wire.endTransmission();
if(i == 0)
{
ownAddr = HDC100X_ADDR3;
break;
}
delay(20); // wait 20ms
Wire.beginTransmission(HDC100X_ADDR4);
i = Wire.endTransmission();
if(i == 0)
{
ownAddr = HDC100X_ADDR4;
break;
}
delay(20); // wait 20ms
}
}
HDCmode = mode;
return writeConfigData(mode|(tempRes<<2)|humiRes|(heaterState<<5));
}
//-----------------------------------------------------------------------
uint8_t HDC100X::begin(uint8_t mode, uint8_t resulution, bool heaterState){
/* sets the mode, resolution and heaterState. Care must be taken, because it will change the temperature reading
** in:
** mode: HDC100X_TEMP/HDC100X_HUMI
** resolution: HDC100X_8BIT(just for the humidity)/HDC100X_11BIT(both)/HDC100X_14BIT(both)
** heaterState: ENABLE/DISABLE
** out:
** high byte of the configuration register
*/
Wire.begin();
HDCmode = mode;
if(mode == HDC100X_HUMI) return writeConfigData(resulution|(heaterState<<5));
else return writeConfigData((resulution<<2)|(heaterState<<5));
}
//######-----------------------------------------------------------------------
void HDC100X::setAddr(uint8_t address){
/* sets the slave address
** in:
** address: slave address byte
** out:
** none
*/
ownAddr = address;
}
//-----------------------------------------------------------------------
void HDC100X::setAddr(bool addr0, bool addr1){
/* sets the slave address
** in:
** addr0: true/false
** addr1: true/false
** out:
** none
*/
ownAddr = 0b1000000 |(addr0|(addr1<<1));
}
//-----------------------------------------------------------------------
void HDC100X::setDrPin(int8_t pin){
dataReadyPin = pin;
}
//######-----------------------------------------------------------------------
//######-----------------------------------------------------------------------
uint8_t HDC100X::setMode(uint8_t mode, uint8_t tempRes, uint8_t humiRes){
/* sets the mode and resolution
** in:
** mode: HDC100X_TEMP_HUMI
** tempRes: HDC100X_11BIT/HDC100X_14BIT
** humiRes: HDC100X_8BIT/HDC100X_11BIT/HDC100X_14BIT
** out:
** high byte of the configuration register
*/
uint8_t tempReg = getConfigReg() & 0xA0;
HDCmode = mode;
return writeConfigData(tempReg|mode|(tempRes<<2)|humiRes);
}
//-----------------------------------------------------------------------
uint8_t HDC100X::setMode(uint8_t mode, uint8_t resolution){
/* sets the mode and resolution
** in:
** mode: HDC100X_TEMP/HDC100X_HUMI
** resolution: HDC100X_8BIT(just for the humidity)/HDC100X_11BIT(both)/HDC100X_14BIT(both)
** out:
** high byte of the configuration register
*/
uint8_t tempReg = getConfigReg() & 0xA0;
HDCmode = mode;
if(mode == HDC100X_HUMI) return writeConfigData(tempReg|resolution);
return writeConfigData(tempReg|(resolution<<2));
}
//######-----------------------------------------------------------------------
//######-----------------------------------------------------------------------
uint8_t HDC100X::setHeater(bool state){
/* turns on the heater to get rid of condensation. Care must be taken, because it will change the temperature reading
** in:
** state: true/false
** out:
** high byte of the configuration register
*/
uint8_t regData = getConfigReg() & 0x5F;
if(state) return writeConfigData(regData|(state<<5));
return writeConfigData(regData);
}
//######-----------------------------------------------------------------------
//######-----------------------------------------------------------------------
bool HDC100X::battLow(void){
// returns a false if input voltage is higher than 2.8V and if lower a true
if(getConfigReg() & 0x08) return true;
return false;
}
//######-----------------------------------------------------------------------
//######-----------------------------------------------------------------------
float HDC100X::getTemp(void){
// returns the a float number of the temperature in degrees Celsius
if(HDCmode == HDC100X_TEMP || HDCmode == HDC100X_TEMP_HUMI)
return ((float)getRawTemp()/65536.0*165.0-40.0);
return 0.0;
}
//-----------------------------------------------------------------------
float HDC100X::getHumi(void){
// returns the a float number of the humidity in percent
if(HDCmode == HDC100X_HUMI || HDCmode == HDC100X_TEMP_HUMI)
return ((float)getRawHumi()/65536.0*100.0);
return 0.0;
}
//######-----------------------------------------------------------------------
//######-----------------------------------------------------------------------
uint16_t HDC100X::getRawTemp(void){
// returns the raw 16bit data of the temperature register
if(HDCmode == HDC100X_TEMP || HDCmode == HDC100X_TEMP_HUMI)
return read2Byte(HDC100X_TEMP_REG);
return 0;
}
//-----------------------------------------------------------------------
uint16_t HDC100X::getRawHumi(void){
// returns the raw 16bit data of the humidity register
if(HDCmode == HDC100X_HUMI || HDCmode == HDC100X_TEMP_HUMI)
return read2Byte(HDC100X_HUMI_REG);
return 0;
}
//######-----------------------------------------------------------------------
//######-----------------------------------------------------------------------
uint8_t HDC100X::getConfigReg(void){
// returns the high byte of the configuration register
return (read2Byte(HDC100X_CONFIG_REG)>>8);
}
//######-----------------------------------------------------------------------
//######-----------------------------------------------------------------------
uint16_t HDC100X::read2Byte(uint8_t reg){
/* reads two bytes from the defined register
** in:
** reg: HDC100X_TEMP_REG/HDC100X_HUMI_REG/HDC100X_CONFIG_REG/HDC100X_ID1_REG/HDC100X_ID2_REG/HDC100X_ID3_REG
** out:
** two byte of data from the defined register
*/
uint16_t data=0;
setRegister(reg);
Wire.requestFrom(ownAddr, 2U);
if(Wire.available()>=2){
data = Wire.read()<<8;
data += Wire.read();
}
return data;
}
uint8_t HDC100X::writeConfigData(uint8_t config){
/* writes the config byte to the configuration register
** in:
** config: one byte
** out:
** one byte 0:success 1:data too long to fit in transmit buffer 2:received NACK on transmit of address 3:received NACK on transmit of data 4:other error
*/
Wire.beginTransmission(ownAddr);
Wire.write(HDC100X_CONFIG_REG);
Wire.write(config);
Wire.write(0x00); //the last 8 bits are always 0
return Wire.endTransmission();
}
//######-----------------------------------------------------------------------
//######-----------------------------------------------------------------------
//PRIVATE:
//######-----------------------------------------------------------------------
//######-----------------------------------------------------------------------
void HDC100X::setRegister(uint8_t reg){
/* set the register for the next read or write cycle
** in:
** reg: HDC100X_TEMP_REG/HDC100X_HUMI_REG/HDC100X_CONFIG_REG/HDC100X_ID1_REG/HDC100X_ID2_REG/HDC100X_ID3_REG
** out:
** none
*/
Wire.beginTransmission(ownAddr);
Wire.write(reg);
Wire.endTransmission();
delay(10); // wait a little so that the sensor can set its register
}