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