TI HDC1000 Temperature and Humidity Sensor
HDC1000.cpp
- Committer:
- Rhyme
- Date:
- 2017-04-17
- Revision:
- 1:f2c04c5b28ab
- Parent:
- 0:1db0d0071723
- Child:
- 2:f574cd898cba
File content as of revision 1:f2c04c5b28ab:
#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
HDC1000::HDC1000(PinName sda, PinName scl, PinName rdy, int addr) : m_i2c(sda, scl), m_rdy(rdy), m_addr(addr<<1) {
// HDC1000::HDC1000(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr<<1) {
// 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 ;
int32_t ltemp ;
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) ;
/*
ltemp = (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)(ltemp)/ (float)0x3FFF)*165.0 - 40.0 ;
*/
return( ftemp ) ;
}
float HDC1000::readHumidity(void)
{
uint16_t utemp, uhume ;
int mode ;
int32_t lhume ;
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) ;
/*
lhume = (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
fhum = ((float)(lhume) / (float)0x3FFF) * 100.0 ;
*/
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) ;
#if 0
utemp = (utemp >> 2) & 0x3FFF ;
uhume = (uhume >> 2) & 0x3FFF ;
*ftemp = ((float)(utemp)/ (float)0x3FFF)*165.0 - 40.0 ;
*fhume = ((float)(uhume) / (float)0x3FFF) * 100.0 ;
#endif
}
/* for mode 0 */
uint16_t HDC1000::getTemperature(void)
{
uint16_t temp ;
uint8_t data[2] ;
float delay ;
data[0] = REG_TEMPERATURE ;
data[1] = (m_addr << 1) | 0x01 ;
m_i2c.write(m_addr, (const char*)data, 2, true);
while(m_rdy == 1) { } /* wait for rdy */
// delay = getTDelay() ;
// wait_us(1000 * delay) ;
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] ;
float delay ;
// readRegs(REG_HUMIDITY, data, 2) ;
data[0] = REG_HUMIDITY ;
data[1] = (m_addr << 1) | 0x01 ;
m_i2c.write(m_addr, (const char*)data, 2, true);
while(m_rdy == 1) { } /* wait for rdy */
// delay = getHDelay() ;
// wait_us(1000 * delay) ;
// wait(0.1) ;
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)
{
float delay ;
uint8_t data[4] = { 0, 0, 0, 0 } ;
int mode ;
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);
while(m_rdy == 1) { } /* wait for rdy */
// delay = getTDelay() + getHDelay() ;
// wait_us(1000 * delay) ;
// m_i2c.write(m_addr,(const char *)data, 1, true);
// while(m_rdy == 1) { } /* wait for rdy */
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);
}