Isaac Khader / htu21d_for_weather_shield

Dependents:   SPARKFUN_WEATHER_SHIELD

Fork of htu21d by Kevin Braun

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers htu21d.cpp Source File

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