Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
htu21d.cpp
00001 /** 00002 HTU21D / HPP828E031 driver for mbed. 00003 - Includes RTOS hooks if RTOS is detected during compile. 00004 Author: Kevin Braun 00005 **/ 00006 00007 #include "htu21d.h" 00008 00009 double theTempIs = 0.0; 00010 double theHumIs = 0.0; 00011 00012 #if not defined HTU21Di2cLOWLEVEL 00013 char htuBuffer[8]; 00014 #endif 00015 00016 //--------------------------------------------------------------------------------------------------------------------------------------// 00017 //Contstructor 00018 00019 htu21d::htu21d(PinName sda, PinName scl) : _i2c(sda, scl) { 00020 _i2c.frequency(400000); 00021 } 00022 00023 htu21d::htu21d(PinName sda, PinName scl, int i2cFrequency) : _i2c(sda, scl) { 00024 _i2c.frequency(i2cFrequency); 00025 } 00026 00027 //--------------------------------------------------------------------------------------------------------------------------------------// 00028 //Destructor 00029 00030 htu21d::~htu21d() { 00031 } 00032 00033 //--------------------------------------------------------------------------------------------------------------------------------------// 00034 //Perform a soft reset on the HTU21D. REturn of 1 = ok, 0 = timeout. 00035 00036 int htu21d::softReset() { 00037 int htu21 = 0; 00038 #if defined HTU21Di2cLOWLEVEL 00039 _i2c.start(); 00040 htu21 = _i2c.write(HTU21Di2cWRITE); //i2c, 1 = ack 00041 if(htu21 == 1) { 00042 _i2c.write(HTU21DRESET); //soft reset, must wait 15mS 00043 _i2c.stop(); 00044 wait_ms(16); //must wait a least 15mS for reset to finish 00045 htu21d::getSNReg(); //go load up the s/n registers 00046 } 00047 return(htu21); 00048 #else 00049 htuBuffer[0] = HTU21DRESET; 00050 htu21 = _i2c.write(HTU21Di2cWRITE, htuBuffer, 1, false); 00051 wait_ms(16); 00052 htu21d::getSNReg(); 00053 return(!(htu21)); 00054 #endif 00055 } 00056 00057 //--------------------------------------------------------------------------------------------------------------------------------------// 00058 //Get the HTU21D user register. Returns 8 bit register. 00059 00060 uint8_t htu21d::getUserReg() { 00061 #if defined HTU21Di2cLOWLEVEL 00062 int htu21 = 0; 00063 uint8_t htu21data = 0; 00064 _i2c.start(); 00065 htu21 = _i2c.write(HTU21Di2cWRITE); //i2c, 1 = ack 00066 if(htu21 == 1) { 00067 _i2c.write(HTU21DREADUSER); 00068 _i2c.start(); 00069 htu21 = _i2c.write(HTU21Di2cREAD); 00070 htu21data = _i2c.read(0); 00071 _i2c.stop(); 00072 } 00073 return(htu21data); 00074 #else 00075 htuBuffer[0] = HTU21DREADUSER; 00076 _i2c.write(HTU21Di2cWRITE, htuBuffer, 1, true); 00077 if(!(_i2c.read(HTU21Di2cREAD, htuBuffer, 1, false))) { 00078 return(htuBuffer[0]); 00079 } else { 00080 return(0); 00081 } 00082 #endif 00083 } 00084 00085 //--------------------------------------------------------------------------------------------------------------------------------------// 00086 //Turn ON the heater the HTU21D user register. 00087 00088 int htu21d::heaterOn() { 00089 uint8_t htu21data = htu21d::getUserReg(); 00090 htu21data |= HTU21DHEATER; 00091 #if defined HTU21Di2cLOWLEVEL 00092 int htu21 = 0; 00093 _i2c.start(); 00094 htu21 = _i2c.write(HTU21Di2cWRITE); //i2c, 1 = ack 00095 if(htu21 == 1) { 00096 _i2c.write(HTU21DWRITEUSER); 00097 htu21 = _i2c.write(htu21data); 00098 _i2c.stop(); 00099 } 00100 return(htu21); 00101 #else 00102 htuBuffer[0] = HTU21DWRITEUSER; 00103 htuBuffer[1] = htu21data; 00104 return(_i2c.write(HTU21Di2cWRITE, htuBuffer, 2, false)); 00105 #endif 00106 } 00107 00108 //--------------------------------------------------------------------------------------------------------------------------------------// 00109 //Turn OFF the heater the HTU21D user register. 00110 00111 int htu21d::heaterOff() { 00112 uint8_t htu21data = htu21d::getUserReg(); 00113 htu21data &= ~HTU21DHEATER; 00114 #if defined HTU21Di2cLOWLEVEL 00115 int htu21 = 0; 00116 _i2c.start(); 00117 htu21 = _i2c.write(HTU21Di2cWRITE); //i2c, 1 = ack 00118 if(htu21 == 1) { 00119 _i2c.write(HTU21DWRITEUSER); 00120 htu21 = _i2c.write(htu21data); 00121 _i2c.stop(); 00122 } 00123 return(htu21); 00124 #else 00125 htuBuffer[0] = HTU21DWRITEUSER; 00126 htuBuffer[1] = htu21data; 00127 return(_i2c.write(HTU21Di2cWRITE, htuBuffer, 2, false)); 00128 #endif 00129 00130 } 00131 00132 //--------------------------------------------------------------------------------------------------------------------------------------// 00133 //Get the status of the heater the HTU21D user register. 0 = off, 4 = on. 00134 00135 uint8_t htu21d::getHeater() { 00136 uint8_t htu21data = htu21d::getUserReg(); 00137 htu21data &= HTU21DHEATER; 00138 return(htu21data); 00139 } 00140 00141 //--------------------------------------------------------------------------------------------------------------------------------------// 00142 //generic routine to get temp or humidity from HTU21D. 00143 //Returns 14 bits of data (anded 0xFFFC) or 0000 if i2c timeout occurs. 00144 //After a read temp or humidity command, HTU21D responds with NACKs until data is ready. 00145 //NOTE: Use non-hold commands 00146 00147 uint16_t htu21d::getData(uint8_t reg) { 00148 int htu21cnt = 0; //number of NACKs before ACK or timeout 00149 #if defined HTU21Di2cLOWLEVEL 00150 uint16_t htu21data = 0; //returned data 00151 int htu21 = 0; //ACK flag 00152 _i2c.start(); 00153 htu21 = _i2c.write(HTU21Di2cWRITE); 00154 _i2c.write(reg); //read temp, no hold 00155 _i2c.stop(); 00156 if(htu21 == 0) return 0; //HTU21T not responding 00157 do { 00158 htu21cnt++; 00159 _i2c.start(); 00160 htu21 = _i2c.write(HTU21Di2cREAD); 00161 if(htu21 == 1) { 00162 htu21data = _i2c.read(1) << 8; 00163 htu21data |= _i2c.read(0) & 0xFC; 00164 _i2c.stop(); 00165 } 00166 wait_us(1000); 00167 } while((htu21cnt < 100) && (htu21 == 0)); //htu21cnt takes 55 to get temp, 16 for humidity (at 1mS loops) 00168 00169 if(htu21 == 0) return 0; //HTU21D ACK response timed out 00170 return(htu21data); //return 14 bit value 00171 #else 00172 htuBuffer[0] = reg; 00173 _i2c.write(HTU21Di2cWRITE, htuBuffer, 1, false); 00174 do { 00175 htu21cnt++; 00176 if(!(_i2c.read(HTU21Di2cREAD, htuBuffer, 2, false))) { 00177 return((htuBuffer[0] << 8) | htuBuffer[1]); 00178 } 00179 wait_us(1000); 00180 } while(htu21cnt < 100); 00181 return 0; 00182 #endif 00183 } 00184 00185 //--------------------------------------------------------------------------------------------------------------------------------------// 00186 //get temperature from HTU21D in degrees C. Returns with 255.0 if HTU21D had timed out. 00187 00188 float htu21d::getTemp() { 00189 uint16_t getData = htu21d::getData(HTU21DtempNOHOLD); 00190 if (getData == 0) return(255.0); //return with error 00191 double tempData = (double)getData / 65536.0; 00192 theTempIs = -46.85 + (175.72 * tempData); 00193 return(theTempIs); 00194 } 00195 00196 //--------------------------------------------------------------------------------------------------------------------------------------// 00197 //get humidity from HTU21D in percentage. Returns with 255.0 if HTU21D had timed out. 00198 00199 float htu21d::getHum() { 00200 uint16_t getData = htu21d::getData(HTU21DhumNOHOLD); 00201 if (getData == 0) return(255.0); //return with error 00202 double tempData = (double)getData / 65536.0; 00203 theHumIs = -6.0 + (125.0 * tempData); 00204 return(theHumIs); 00205 } 00206 00207 //--------------------------------------------------------------------------------------------------------------------------------------// 00208 //Calculate the Dew Point from getTemp and getHum. User must first execute both getTemp and getHum for an accurate result. 00209 //Calculations come from DHT library 00210 /* Copyright (C) Wim De Roeve 00211 * based on DHT22 sensor library by HO WING KIT 00212 * Arduino DHT11 library 00213 */ 00214 00215 float htu21d::getDewPt() { 00216 // dewPoint function NOAA 00217 // reference: http://wahiduddin.net/calc/density_algorithms.htm 00218 double A0= 373.15/(273.15 + (double)theTempIs); 00219 double SUM = -7.90298 * (A0-1); 00220 SUM += 5.02808 * log10(A0); 00221 SUM += -1.3816e-7 * (pow(10, (11.344*(1-1/A0)))-1) ; 00222 SUM += 8.1328e-3 * (pow(10,(-3.49149*(A0-1)))-1) ; 00223 SUM += log10(1013.246); 00224 double VP = pow(10, SUM-3) * theHumIs; 00225 double T = log(VP/0.61078); // temp var 00226 return (241.88 * T) / (17.558-T); 00227 } 00228 00229 float htu21d::getDewPtFast() { 00230 // delta max = 0.6544 wrt dewPoint() 00231 // 5x faster than dewPoint() 00232 // reference: http://en.wikipedia.org/wiki/Dew_point 00233 double h21DtzA = 17.271; 00234 double h21DtzB = 237.7; 00235 double h21DtzC = (h21DtzA * theTempIs) / (h21DtzB + theTempIs) + log(theHumIs/100); 00236 double h21DtzD = (h21DtzB * h21DtzC) / (h21DtzA - h21DtzC); 00237 return (h21DtzD); 00238 } 00239 00240 //--------------------------------------------------------------------------------------------------------------------------------------// 00241 //Get the HTU21D serial number registers. Returns 64 bit register. 00242 //should return 0x4854 00xx xxxx 32xx 00243 00244 void htu21d::getSNReg() { 00245 //get 16 bit SNC register, 8 bit SNC-CRC, 16 bit SNA register, 8 bit SNA-CRC 00246 #if defined HTU21Di2cLOWLEVEL 00247 int htu21 = 0; 00248 _i2c.start(); 00249 htu21 = _i2c.write(HTU21Di2cWRITE); //i2c, 1 = ack 00250 if(htu21 == 1) { 00251 _i2c.write(HTU21SNAC1); 00252 _i2c.write(HTU21SNAC2); 00253 _i2c.start(); 00254 htu21 = _i2c.write(HTU21Di2cREAD); 00255 HTU21sn.HTU21D_snc = _i2c.read(1) << 8; 00256 HTU21sn.HTU21D_snc |= _i2c.read(1); 00257 HTU21sn.HTU21D_crcc = _i2c.read(1); 00258 HTU21sn.HTU21D_sna = _i2c.read(1) << 8; 00259 HTU21sn.HTU21D_sna |= _i2c.read(1); 00260 HTU21sn.HTU21D_crca = _i2c.read(0); 00261 _i2c.stop(); 00262 } else { 00263 HTU21sn.HTU21D_snc = HTU21sn.HTU21D_crcc = HTU21sn.HTU21D_sna = HTU21sn.HTU21D_crca = 0; 00264 } 00265 #else 00266 htuBuffer[0] = HTU21SNAC1; 00267 htuBuffer[1] = HTU21SNAC2; 00268 _i2c.write(HTU21Di2cWRITE, htuBuffer, 2, true); 00269 if(!(_i2c.read(HTU21Di2cREAD, htuBuffer, 6, false))) { 00270 HTU21sn.HTU21D_snc = (htuBuffer[0] << 8) | htuBuffer[1]; 00271 HTU21sn.HTU21D_crcc = htuBuffer[2]; 00272 HTU21sn.HTU21D_sna = (htuBuffer[3] << 8) | htuBuffer[4]; 00273 HTU21sn.HTU21D_crca = htuBuffer[5]; 00274 } else { 00275 HTU21sn.HTU21D_snc = HTU21sn.HTU21D_crcc = HTU21sn.HTU21D_sna = HTU21sn.HTU21D_crca = 0; 00276 } 00277 #endif 00278 00279 //get 32 bit SNB register, 32 bit SNB-CRC - regs are intermixed 00280 #if defined HTU21Di2cLOWLEVEL 00281 htu21 = 0; 00282 _i2c.start(); 00283 htu21 = _i2c.write(HTU21Di2cWRITE); //i2c, 1 = ack 00284 if(htu21 == 1) { 00285 _i2c.write(HTU21SNB1); 00286 _i2c.write(HTU21SNB2); 00287 _i2c.start(); 00288 htu21 = _i2c.write(HTU21Di2cREAD); 00289 HTU21sn.HTU21D_snb = _i2c.read(1) << 24; 00290 HTU21sn.HTU21D_crcb = _i2c.read(1) << 24; 00291 HTU21sn.HTU21D_snb |= _i2c.read(1) << 16; 00292 HTU21sn.HTU21D_crcb |= _i2c.read(1) << 16; 00293 HTU21sn.HTU21D_snb |= _i2c.read(1) << 8; 00294 HTU21sn.HTU21D_crcb |= _i2c.read(1) << 8; 00295 HTU21sn.HTU21D_snb |= _i2c.read(1); 00296 HTU21sn.HTU21D_crcb |= _i2c.read(0); 00297 _i2c.stop(); 00298 } else { 00299 HTU21sn.HTU21D_snb = HTU21sn.HTU21D_crcb = 0; 00300 } 00301 #else 00302 htuBuffer[0] = HTU21SNB1; 00303 htuBuffer[1] = HTU21SNB2; 00304 _i2c.write(HTU21Di2cWRITE, htuBuffer, 2, true); 00305 if(!(_i2c.read(HTU21Di2cREAD, htuBuffer, 8, false))) { 00306 HTU21sn.HTU21D_snb = (htuBuffer[0] << 24) | (htuBuffer[2] << 16) | (htuBuffer[4] << 8) | htuBuffer[6]; 00307 HTU21sn.HTU21D_crcb = (htuBuffer[1] << 24) | (htuBuffer[3] << 16) | (htuBuffer[5] << 8) | htuBuffer[7]; 00308 } else { 00309 HTU21sn.HTU21D_snb = HTU21sn.HTU21D_crcb = 0; 00310 } 00311 #endif 00312 } 00313
Generated on Tue Jul 12 2022 18:12:19 by
1.7.2