TI HDC1000 Temperature and Humidity Sensor
HDC1000.cpp
- Committer:
- Rhyme
- Date:
- 2017-04-18
- Revision:
- 2:f574cd898cba
- Parent:
- 1:f2c04c5b28ab
File content as of revision 2:f574cd898cba:
#include "mbed.h" #include "HDC1000.h" #define REG_TEMPERATURE 0x00 #define REG_HUMIDITY 0x01 #define REG_CONFIGURATION 0x02 #define REG_ID_FIRST_WORD 0xFB #define REG_ID_SECOND_WORD 0xFC #define REG_ID_LAST_BYTE 0xFD #define REG_MANUFACTURE_ID 0xFE #define REG_DEVICE_ID 0xFF /* Bit field of Configuration register */ /* bit[15] RST Sowtware Rest Bit 0: Normal 1: Reset * bit[14:13] (Reserved) must be 00 * bit[12] MODE 0:Aquire Temp/Hum separately(16bit each) 1:Aquire both Temp/Hum same time (32bit) * bit[11] BTST Battery Test(?) 0:VDD > 2.8V 1:VDD < 2.8V * bit[10] TRES Temperature Resolution 0:14bit 1:11bit * bit[9:8] HRES Humidity Resolution 00:14bit 01:11bit 10:8bit * bit[7:0] (Reserved) must be 00000000 */ #define BIT_RESET 0x8000 #define BIT_MODE 0x1000 #define BIT_BTST 0x0800 #define BIT_TRES 0x0400 #define BIT_HRES14 0x0000 #define BIT_HRES11 0x0100 #define BIT_HRES08 0x0200 #if USE_READY_PIN HDC1000::HDC1000(PinName sda, PinName scl, PinName rdy, int addr) : m_i2c(sda, scl), m_rdy(rdy), m_addr(addr<<1) { #else HDC1000::HDC1000(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr<<1) { #endif // activate the peripheral } HDC1000::~HDC1000(void) { } void HDC1000::reset(void) { uint16_t conf = 0x8000 ; setConfig(conf) ; } float HDC1000::u2f_temp(uint16_t utemp) { float ftemp ; utemp = (utemp >> 2) & 0x3FFF ; // note: the data sheet suggests to use 0x10000 for denominator // but to allow 100% I chose 0xFFFF instead, I may be wrong ftemp = ((float)(utemp)/ (float)0x3FFF)*165.0 - 40.0 ; return( ftemp ) ; } float HDC1000::u2f_hume(uint16_t uhume) { float fhume ; uhume = (uhume>>2) & 0x3FFF ; // note: the data sheet suggests to use 0x10000 for denominator // but to allow 100% I chose 0xFFFF instead, I may be wrong fhume = ((float)(uhume) / (float)0x3FFF) * 100.0 ; return( fhume ) ; } float HDC1000::readTemperature(void) { uint16_t utemp, uhum ; int mode ; float ftemp ; mode = getMode() ; switch(mode) { case 0: /* temp or hum can be acquired */ utemp = getTemperature() ; break ; case 1: /* temp and hum can be acquired */ getData(&utemp, &uhum) ; break ; default: printf("Error: unexpected mode %d\n",mode) ; break ; } // printf("utemp = 0x%04X ", utemp) ; ftemp = u2f_temp(utemp) ; return( ftemp ) ; } float HDC1000::readHumidity(void) { uint16_t utemp, uhume ; int mode ; float fhume ; mode = getMode() ; switch(mode) { case 0: /* temp or hum can be acquired */ uhume = getHumidity() ; break ; case 1: /* temp and hum can be acquired */ getData(&utemp, &uhume) ; break ; default: printf("Error: unexpected mode %d\n",mode) ; break ; } // printf("uhume = 0x%04X\n", uhume) ; fhume = u2f_hume(uhume) ; return( fhume ) ; } void HDC1000::readData(float *ftemp, float *fhume) { uint16_t utemp, uhume ; getData(&utemp, &uhume) ; // printf("utemp: 0x%04X, uhume: 0x%04X\n", utemp, uhume) ; *ftemp = u2f_temp(utemp) ; *fhume = u2f_hume(uhume) ; } /* for mode 0 */ uint16_t HDC1000::getTemperature(void) { uint16_t temp ; uint8_t data[2] ; #if USE_READY_PIN float delay ; #endif data[0] = REG_TEMPERATURE ; data[1] = (m_addr << 1) | 0x01 ; m_i2c.write(m_addr, (const char*)data, 2, true); #if USE_READY_PIN while(m_rdy == 1) { } /* wait for rdy */ #else delay = getTDelay() ; printf("Temp Delay = %.2f\n", delay) ; wait_us(1000 * delay) ; #endif m_i2c.read(m_addr, (char *)data, 2); temp = (data[0] << 8) | data[1] ; return( temp ) ; } uint16_t HDC1000::getHumidity(void) { uint16_t hume ; uint8_t data[2] ; #if USE_READY_PIN float delay ; #endif data[0] = REG_HUMIDITY ; data[1] = (m_addr << 1) | 0x01 ; m_i2c.write(m_addr, (const char*)data, 2, true); #if USE_READY_PIN while(m_rdy == 1) { } /* wait for rdy */ #else delay = getHDelay() ; printf("Hume Delay = %.2f\n", delay) ; wait_us(1000 * delay) ; #endif m_i2c.read(m_addr, (char *)data, 2); hume = (data[0] << 8) | data[1] ; return( hume ) ; } /* for mode 1 */ void HDC1000::getData(uint16_t *temp, uint16_t *hume) { uint8_t data[4] = { 0, 0, 0, 0 } ; int mode ; #if USE_READY_PIN float delay ; #endif mode = getMode() ; if (mode == 0) { *temp = getTemperature() ; *hume = getHumidity() ; } else { /* mode == 1 */ data[0] = REG_TEMPERATURE ; data[1] = (m_addr << 1) | 0x01 ; m_i2c.write(m_addr,(const char *)data, 2, false); #if USE_READY_PIN while(m_rdy == 1) { } /* wait for rdy */ #else delay = getTDelay() + getHDelay() ; printf("Delay = %.2f ms\n", delay) ; wait( delay / 1000.0 ) ; #endif m_i2c.read(m_addr, (char *)data, 4); *temp = (data[0] << 8) | data[1] ; *hume = (data[2] << 8) | data[3] ; } } void HDC1000::setConfig(uint16_t conf) { uint8_t data[3] ; data[0] = REG_CONFIGURATION ; data[1] = (conf >> 8) & 0xFF ; data[2] = conf & 0xFF ; writeRegs(data, 3) ; } uint16_t HDC1000::getConfig(void) { uint8_t data[2] ; uint16_t conf ; readRegs(REG_CONFIGURATION, data, 2) ; conf = (data[0] << 8) | data[1] ; return( conf ) ; } void HDC1000::setMode(int mode) { uint16_t conf ; conf = getConfig() ; if (mode) { conf |= BIT_MODE ; } else { conf ^= BIT_MODE ; } setConfig( conf ) ; } int HDC1000::getMode(void) { uint16_t conf ; int mode ; conf = getConfig() ; if (conf & BIT_MODE) { mode = 1 ; } else { mode = 0 ; } return( mode ) ; } void HDC1000::setTres(int tres) { uint16_t conf ; conf = getConfig() ; if (tres) { conf |= BIT_TRES ; } else { conf ^= BIT_TRES ; } } int HDC1000::getTres(void) { uint16_t conf ; int tres ; conf = getConfig() ; if (conf & BIT_TRES) { tres = 1 ; } else { tres = 0 ; } return( tres ) ; } void HDC1000::setHres(int hres) { uint16_t conf ; conf = getConfig() ; conf ^= (BIT_HRES11 | BIT_HRES08) ; conf |= ((hres & 0x03) << 8) ; } int HDC1000::getHres(void) { uint16_t conf ; int hres ; conf = getConfig() ; hres = (conf >> 8)&0x03 ; return( hres ) ; } void HDC1000::getSerialID(uint8_t data[]) { uint8_t udata[2] ; readRegs(REG_ID_FIRST_WORD, &data[0], 2) ; readRegs(REG_ID_SECOND_WORD, &data[2], 2) ; readRegs(REG_ID_LAST_BYTE, udata, 2) ; data[4] = udata[0] ; } uint16_t HDC1000::getManufactureID(void) /* 0x5449 : Texas Instruments */ { uint8_t data[2] ; uint16_t id ; readRegs(REG_MANUFACTURE_ID, data, 2) ; id = (data[0] << 8) | data[1] ; return( id ) ; } uint16_t HDC1000::getDeviceID(void) /* 0x1000 */ { uint8_t data[2] ; uint16_t id ; readRegs(REG_DEVICE_ID, data, 2) ; id = (data[0] << 8) | data[1] ; return( id ) ; } float HDC1000::getTDelay(void) { int tres ; float tdelay ; tres = getTres() ; switch(tres) { case 0: /* 14bit */ tdelay = 6.35 ; break ; case 1: /* 11bit */ tdelay = 3.65 ; break ; default: tdelay = 6.35 ; break ; } return(tdelay) ; } float HDC1000::getHDelay(void) { int hres ; float hdelay ; hres = getHres() ; switch(hres) { case 0: /* 14bit */ hdelay = 6.5 ; break ; case 1: /* 11bit */ hdelay = 3.85 ; break ; case 2: /* 8bit */ hdelay = 2.5 ; break ; default: hdelay = 6.5 ; /* let's use the longest value */ break ; } return(hdelay) ; } float HDC1000::getDelay(void) { float tdelay, hdelay ; tdelay = getTDelay() ; hdelay = getHDelay() ; return( tdelay + hdelay ) ; } void HDC1000::readRegs(int addr, uint8_t * data, int len) { char t[1] = {addr}; m_i2c.write(m_addr, t, 1, true); m_i2c.read(m_addr, (char *)data, len) ; } void HDC1000::writeRegs(uint8_t * data, int len) { m_i2c.write(m_addr, (char *)data, len); }