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++
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
|
|
}
|