TI HDC1000 Temperature and Humidity Sensor
Embed:
(wiki syntax)
Show/hide line numbers
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 }
Generated on Mon Jul 25 2022 05:24:50 by
1.7.2