TI HDC1000 Temperature and Humidity Sensor

Dependents:   test_HDC1000

Files at this revision

API Documentation at this revision

Comitter:
Rhyme
Date:
Mon Apr 17 02:49:07 2017 +0000
Child:
1:f2c04c5b28ab
Commit message:
First working version

Changed in this revision

HDC1000.cpp Show annotated file Show diff for this revision Revisions of this file
HDC1000.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HDC1000.cpp	Mon Apr 17 02:49:07 2017 +0000
@@ -0,0 +1,349 @@
+#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::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 ;
+    }
+    // note: the data sheet suggests to use 0x10000 for denominator
+    // but to allow 100% I chose 0xFFFF instead, I may be wrong
+    printf("utemp = 0x%04X ", utemp) ;
+    ltemp = (utemp >> 2) & 0x3FFF ;
+    
+    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 fhum ;
+
+    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 ;
+    }
+    // note: the data sheet suggests to use 0x10000 for denominator
+    // but to allow 100% I chose 0xFFFF instead, I may be wrong
+    printf("uhume = 0x%04X\n", uhume) ;
+    lhume = (uhume>>2) & 0x3FFF ;
+ 
+    fhum = ((float)(lhume) / (float)0x3FFF) * 100.0 ;
+    return( fhum ) ;
+}
+
+void HDC1000::readData(float *ftemp, float *fhume)
+{
+    uint16_t utemp, uhume ;
+    getData(&utemp, &uhume) ;
+    printf("utemp: 0x%04X, uhume: 0x%04X\n", utemp, uhume) ;
+    utemp = (utemp >> 2) & 0x3FFF ;
+    uhume = (uhume >> 2) & 0x3FFF ;
+    *ftemp = ((float)(utemp)/ (float)0x3FFF)*165.0 - 40.0 ;
+    *fhume = ((float)(uhume) / (float)0x3FFF) * 100.0 ;
+}
+/* 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);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HDC1000.h	Mon Apr 17 02:49:07 2017 +0000
@@ -0,0 +1,60 @@
+#ifndef _HDC1000_H_
+#define _HDC1000_H_
+#include "mbed.h"
+/**
+ * HDC1000 Integrated Low Power Humidity and Temperature Digital Sensor 
+ * I2C address: 0x40 
+ */
+
+class HDC1000 {
+public:
+ /**
+ *  constructor
+ *
+ * @param sda SDA pin
+ * @param scl SCL pin
+ * @param addr address of the I2C peripheral
+ */
+// HDC1000(PinName sda, PinName scl, int addr=0x40) ;
+HDC1000(PinName sda, PinName scl, PinName rdy, int addr=0x40) ;
+ 
+~HDC1000() ;
+
+float    readTemperature(void) ;
+float    readHumidity(void) ;
+
+void     reset(void) ;
+
+/* for mode 0 */
+uint16_t getTemperature(void) ;
+uint16_t getHumidity(void) ;
+void     readData(float *temp, float *hume) ;
+
+/* for mode 1 */
+void     getData(uint16_t *temp, uint16_t *hume) ;
+
+void     setConfig(uint16_t conf) ;
+uint16_t getConfig(void) ;
+void     setMode(int mode) ;
+int      getMode(void) ;
+void     setTres(int tres) ;
+int      getTres(void) ;
+void     setHres(int hres) ;
+int      getHres(void) ;
+void     getSerialID(uint8_t data[]) ; /* returns 5 bytes ID */
+uint16_t getManufactureID(void) ; /* 0x5449 : Texas Instruments */
+uint16_t getDeviceID(void) ;      /* 0x1000 */
+
+float    getTDelay(void) ;
+float    getHDelay(void) ;
+float    getDelay(void) ;
+
+private:
+  I2C m_i2c;
+  DigitalIn m_rdy ;
+  int m_addr;
+  void readRegs(int addr, uint8_t * data, int len);
+  void writeRegs(uint8_t * data, int len);
+} ;
+
+#endif /* _HDC1000_H_ */
\ No newline at end of file