/*********************** 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 }