Motoo Tanaka / HDC1000

Dependents:   test_HDC1000

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers HDC1000.cpp Source File

HDC1000.cpp

00001 #include "mbed.h"
00002 #include "HDC1000.h"
00003 
00004 #define REG_TEMPERATURE    0x00
00005 #define REG_HUMIDITY       0x01
00006 #define REG_CONFIGURATION  0x02
00007 #define REG_ID_FIRST_WORD  0xFB
00008 #define REG_ID_SECOND_WORD 0xFC
00009 #define REG_ID_LAST_BYTE   0xFD
00010 #define REG_MANUFACTURE_ID 0xFE
00011 #define REG_DEVICE_ID      0xFF
00012 
00013 /* Bit field of Configuration register */
00014 /* bit[15]     RST Sowtware Rest Bit 0: Normal 1: Reset
00015  * bit[14:13] (Reserved) must be 00
00016  * bit[12]     MODE 0:Aquire Temp/Hum separately(16bit each) 1:Aquire both Temp/Hum same time (32bit)
00017  * bit[11]     BTST  Battery Test(?) 0:VDD > 2.8V 1:VDD < 2.8V
00018  * bit[10]     TRES  Temperature Resolution 0:14bit 1:11bit
00019  * bit[9:8]    HRES  Humidity Resolution 00:14bit 01:11bit 10:8bit
00020  * bit[7:0]    (Reserved) must be 00000000
00021  */
00022 #define BIT_RESET          0x8000
00023 #define BIT_MODE           0x1000
00024 #define BIT_BTST           0x0800
00025 #define BIT_TRES           0x0400
00026 #define BIT_HRES14         0x0000
00027 #define BIT_HRES11         0x0100
00028 #define BIT_HRES08         0x0200
00029 
00030 #if USE_READY_PIN
00031 HDC1000::HDC1000(PinName sda, PinName scl, PinName rdy, int addr) : m_i2c(sda, scl), m_rdy(rdy), m_addr(addr<<1) {
00032 #else
00033 HDC1000::HDC1000(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr<<1) {
00034 #endif
00035     // activate the peripheral
00036 }
00037 
00038 HDC1000::~HDC1000(void)
00039 {
00040 }
00041 
00042 void HDC1000::reset(void)
00043 {
00044     uint16_t conf = 0x8000 ;
00045     setConfig(conf) ;
00046 }
00047 
00048 float    HDC1000::u2f_temp(uint16_t utemp) 
00049 {
00050     float ftemp ;
00051     
00052     utemp = (utemp >> 2) & 0x3FFF ;
00053     // note: the data sheet suggests to use 0x10000 for denominator
00054     // but to allow 100% I chose 0xFFFF instead, I may be wrong
00055     ftemp = ((float)(utemp)/ (float)0x3FFF)*165.0 - 40.0 ;
00056     return( ftemp ) ;
00057 }
00058 
00059 float    HDC1000::u2f_hume(uint16_t uhume) 
00060 {
00061     float fhume ;
00062     uhume = (uhume>>2) & 0x3FFF ;
00063     
00064     // note: the data sheet suggests to use 0x10000 for denominator
00065     // but to allow 100% I chose 0xFFFF instead, I may be wrong
00066     fhume = ((float)(uhume) / (float)0x3FFF) * 100.0 ;
00067     return( fhume ) ;
00068 }
00069 
00070 float    HDC1000::readTemperature(void) 
00071 {
00072     uint16_t utemp, uhum ;
00073     int mode ;
00074     float ftemp ;
00075 
00076     mode = getMode() ;
00077     switch(mode) {
00078     case 0: /* temp or hum can be acquired */
00079         utemp = getTemperature() ;
00080         break ;
00081     case 1: /* temp and hum can be acquired */
00082         getData(&utemp, &uhum) ;
00083         break ;
00084     default:
00085         printf("Error: unexpected mode %d\n",mode) ;
00086         break ;
00087     }
00088 
00089 //    printf("utemp = 0x%04X ", utemp) ;
00090     ftemp = u2f_temp(utemp) ;
00091     return( ftemp ) ;
00092 }
00093 
00094 float    HDC1000::readHumidity(void) 
00095 {
00096     uint16_t utemp, uhume ;
00097     int mode ;
00098     float fhume ;
00099 
00100     mode = getMode() ;
00101     switch(mode) {
00102     case 0: /* temp or hum can be acquired */
00103         uhume = getHumidity() ;
00104         break ;
00105     case 1: /* temp and hum can be acquired */
00106         getData(&utemp, &uhume) ;
00107         break ;
00108     default: 
00109         printf("Error: unexpected mode %d\n",mode) ;
00110         break ;
00111     }
00112 
00113 //    printf("uhume = 0x%04X\n", uhume) ;
00114     fhume = u2f_hume(uhume) ;
00115     return( fhume ) ;
00116 }
00117 
00118 void HDC1000::readData(float *ftemp, float *fhume)
00119 {
00120     uint16_t utemp, uhume ;
00121     getData(&utemp, &uhume) ;
00122 //    printf("utemp: 0x%04X, uhume: 0x%04X\n", utemp, uhume) ;
00123     *ftemp = u2f_temp(utemp) ;
00124     *fhume = u2f_hume(uhume) ;
00125 }
00126 
00127 /* for mode 0 */
00128 uint16_t HDC1000::getTemperature(void) 
00129 {
00130     uint16_t temp ;
00131     uint8_t data[2] ;
00132 #if USE_READY_PIN
00133     float delay ;
00134 #endif
00135     data[0] = REG_TEMPERATURE ;
00136     data[1] = (m_addr << 1) | 0x01 ;
00137     m_i2c.write(m_addr, (const char*)data, 2, true);
00138     
00139 #if USE_READY_PIN
00140     while(m_rdy == 1) { } /* wait for rdy */
00141 #else
00142     delay = getTDelay() ;
00143     printf("Temp Delay = %.2f\n", delay) ;
00144     wait_us(1000 * delay) ;
00145 #endif
00146 
00147     m_i2c.read(m_addr, (char *)data, 2);
00148     temp = (data[0] << 8) | data[1] ;
00149     return( temp ) ;
00150 }
00151 
00152 uint16_t HDC1000::getHumidity(void) 
00153 {
00154     uint16_t hume ;
00155     uint8_t data[2] ;
00156  #if USE_READY_PIN
00157     float delay ;
00158 #endif
00159 
00160     data[0] = REG_HUMIDITY ;
00161     data[1] = (m_addr << 1) | 0x01 ;
00162     m_i2c.write(m_addr, (const char*)data, 2, true);
00163     
00164 #if USE_READY_PIN
00165     while(m_rdy == 1) { } /* wait for rdy */
00166 #else
00167     delay = getHDelay() ;
00168 printf("Hume Delay = %.2f\n", delay) ;
00169     wait_us(1000 * delay) ;
00170 #endif
00171 
00172     m_i2c.read(m_addr, (char *)data, 2);
00173     hume = (data[0] << 8) | data[1] ;
00174     return( hume ) ;
00175 }
00176 
00177 /* for mode 1 */
00178 void     HDC1000::getData(uint16_t *temp, uint16_t *hume) 
00179 {
00180     uint8_t data[4] = { 0, 0, 0, 0 } ;
00181     int mode ;
00182 #if USE_READY_PIN
00183     float delay ;
00184 #endif
00185 
00186     mode = getMode() ;
00187     if (mode == 0) {
00188         *temp = getTemperature() ;
00189         *hume = getHumidity() ;
00190     } else { /* mode == 1 */
00191         data[0] = REG_TEMPERATURE ;
00192         data[1] = (m_addr << 1) | 0x01 ;
00193         m_i2c.write(m_addr,(const char *)data, 2, false);
00194 #if USE_READY_PIN  
00195         while(m_rdy == 1) { } /* wait for rdy */
00196 #else
00197  delay = getTDelay() + getHDelay() ;
00198  printf("Delay = %.2f ms\n", delay) ;
00199  wait( delay / 1000.0 ) ;
00200 #endif
00201         m_i2c.read(m_addr, (char *)data, 4);
00202         *temp = (data[0] << 8) | data[1] ;
00203         *hume = (data[2] << 8) | data[3] ;
00204     }
00205 }
00206 
00207 void     HDC1000::setConfig(uint16_t conf) 
00208 {
00209     uint8_t data[3] ;
00210     data[0] = REG_CONFIGURATION ;
00211     data[1] = (conf >> 8) & 0xFF ;
00212     data[2] = conf & 0xFF ;
00213     writeRegs(data, 3) ;
00214 }
00215 
00216 uint16_t HDC1000::getConfig(void) 
00217 {
00218     uint8_t data[2] ;
00219     uint16_t conf ;
00220     readRegs(REG_CONFIGURATION, data, 2) ;
00221     conf = (data[0] << 8) | data[1] ;
00222     return( conf ) ;
00223 }
00224 
00225 void     HDC1000::setMode(int mode) 
00226 {
00227     uint16_t conf ;
00228     conf = getConfig() ;
00229     if (mode) {
00230         conf |= BIT_MODE ;
00231     } else {
00232         conf ^= BIT_MODE ;
00233     }
00234     setConfig( conf ) ;
00235 }
00236 
00237 int      HDC1000::getMode(void) 
00238 {
00239     uint16_t conf ;
00240     int mode ;
00241     conf = getConfig() ;
00242     if (conf & BIT_MODE) {
00243         mode = 1 ;
00244     } else {
00245         mode = 0 ;
00246     }
00247     return( mode ) ;
00248 }
00249 
00250 void     HDC1000::setTres(int tres) 
00251 {
00252     uint16_t conf ;
00253     conf = getConfig() ;
00254     if (tres) {
00255         conf |= BIT_TRES ;
00256     } else {
00257         conf ^= BIT_TRES ;
00258     }
00259 }
00260 
00261 int      HDC1000::getTres(void) 
00262 {
00263     uint16_t conf ;
00264     int tres ;
00265     conf = getConfig() ;
00266     if (conf & BIT_TRES) {
00267         tres = 1 ;
00268     } else {
00269         tres = 0 ;
00270     }
00271     return( tres ) ;
00272 }
00273 
00274 void     HDC1000::setHres(int hres) 
00275 {
00276     uint16_t conf ;
00277     conf = getConfig() ;
00278     conf ^= (BIT_HRES11 | BIT_HRES08) ;
00279     conf |= ((hres & 0x03) << 8) ;
00280 }
00281 
00282 int      HDC1000::getHres(void) 
00283 {
00284     uint16_t conf ;
00285     int hres ;
00286     conf = getConfig() ;
00287     hres = (conf >> 8)&0x03 ;
00288     return( hres ) ;
00289 }
00290 
00291 void     HDC1000::getSerialID(uint8_t data[]) 
00292 {
00293     uint8_t udata[2] ;
00294     readRegs(REG_ID_FIRST_WORD,  &data[0], 2) ;
00295     readRegs(REG_ID_SECOND_WORD, &data[2], 2) ;
00296     readRegs(REG_ID_LAST_BYTE,      udata, 2) ;
00297     data[4] = udata[0] ;
00298 }
00299 
00300 uint16_t HDC1000::getManufactureID(void)  /* 0x5449 : Texas Instruments */
00301 {
00302     uint8_t data[2] ;
00303     uint16_t id ;
00304     readRegs(REG_MANUFACTURE_ID, data, 2) ;
00305     id = (data[0] << 8) | data[1] ;
00306     return( id ) ;
00307 }
00308 
00309 uint16_t HDC1000::getDeviceID(void)     /* 0x1000 */
00310 {
00311     uint8_t data[2] ;
00312     uint16_t id ;
00313     readRegs(REG_DEVICE_ID, data, 2) ;
00314     id = (data[0] << 8) | data[1] ;
00315     return( id ) ;
00316 }
00317 
00318 float    HDC1000::getTDelay(void) 
00319 {
00320     int   tres ;
00321     float tdelay ;
00322     
00323     tres = getTres() ;
00324         switch(tres) {
00325     case 0: /* 14bit */
00326         tdelay = 6.35 ;
00327         break ;
00328     case 1: /* 11bit */
00329         tdelay = 3.65 ;
00330         break ;
00331     default:
00332         tdelay = 6.35 ;
00333         break ;
00334     }
00335     return(tdelay) ;
00336 }
00337 
00338 float    HDC1000::getHDelay(void) 
00339 {
00340     int   hres ;
00341     float hdelay ;
00342 
00343     hres = getHres() ;
00344     switch(hres) {
00345     case 0: /* 14bit */
00346         hdelay = 6.5 ;
00347         break ;
00348     case 1: /* 11bit */
00349         hdelay = 3.85 ;
00350         break ;
00351     case 2: /*  8bit */
00352         hdelay = 2.5 ;
00353         break ;
00354     default:
00355         hdelay = 6.5 ; /* let's use the longest value */
00356         break ;
00357     }
00358     return(hdelay) ;
00359 }
00360 
00361 float    HDC1000::getDelay(void) 
00362 {
00363     float tdelay, hdelay ;
00364     tdelay = getTDelay() ;
00365     hdelay = getHDelay() ;
00366     return( tdelay + hdelay ) ;
00367 }
00368 
00369 void HDC1000::readRegs(int addr, uint8_t * data, int len) {
00370     char t[1] = {addr};
00371     m_i2c.write(m_addr, t, 1, true);
00372     m_i2c.read(m_addr, (char *)data, len) ;
00373 }
00374 
00375 void HDC1000::writeRegs(uint8_t * data, int len) {
00376     m_i2c.write(m_addr, (char *)data, len);
00377 }