Library for the Measurement Specialties' HTU21D Humidity and Temperature sensor. Code includes device's heater on/off control, serial number access, dew point calculations and RTOS hooks. To date, code tested on GR-PEACH, K64F and KL25Z boards with and w/o RTOS, SDFlash and USB serial Rx interrupts.
Library for the Measurement Specialties / Honeywell HTU21D Humidity and Temperature sensor. Code includes device's heater on/off control, serial number access, dew point calculations and RTOS hooks. To date, code tested on K64F and KL25Z boards with and without RTOS, SDFileSystem and USB serial Rx interrupts.
The HTU21D's serial number is an odd cookie. There are two 16 bit registers and a 32 bit register are combined to generate the serial number. Some of the serial number bit fields are fixed for all devices and some change from part to part.
Revision 3:5c0f8e91d319, committed 2015-04-30
- Comitter:
- loopsva
- Date:
- Thu Apr 30 00:34:03 2015 +0000
- Parent:
- 2:8fbe84ed61e6
- Commit message:
- Removed RTOS mutex dependencies, put onus back on calling program. Option to use hi-level i2c commands, needed for the GR-PEACH which has bugs using low-level i2c commands. Add the line #define HTU21Di2cLOWLEVEL 1 in htu21d.h to use low-level i2c
Changed in this revision
htu21d.cpp | Show annotated file Show diff for this revision Revisions of this file |
htu21d.h | Show annotated file Show diff for this revision Revisions of this file |
diff -r 8fbe84ed61e6 -r 5c0f8e91d319 htu21d.cpp --- a/htu21d.cpp Thu May 22 18:48:46 2014 +0000 +++ b/htu21d.cpp Thu Apr 30 00:34:03 2015 +0000 @@ -6,13 +6,13 @@ #include "htu21d.h" -#ifdef RTOS_H -extern Mutex MutexI2cWait; -#endif - double theTempIs = 0.0; double theHumIs = 0.0; +#if not defined HTU21Di2cLOWLEVEL +char htuBuffer[8]; +#endif + //--------------------------------------------------------------------------------------------------------------------------------------// //Contstructor @@ -34,12 +34,8 @@ //Perform a soft reset on the HTU21D. REturn of 1 = ok, 0 = timeout. int htu21d::softReset() { - -#ifdef RTOS_H - MutexI2cWait.lock(); -#endif - int htu21 = 0; +#if defined HTU21Di2cLOWLEVEL _i2c.start(); htu21 = _i2c.write(HTU21Di2cWRITE); //i2c, 1 = ack if(htu21 == 1) { @@ -48,23 +44,21 @@ wait_ms(16); //must wait a least 15mS for reset to finish htu21d::getSNReg(); //go load up the s/n registers } - -#ifdef RTOS_H - MutexI2cWait.unlock(); + return(htu21); +#else + htuBuffer[0] = HTU21DRESET; + htu21 = _i2c.write(HTU21Di2cWRITE, htuBuffer, 1, false); + wait_ms(16); + htu21d::getSNReg(); + return(!(htu21)); #endif - - return(htu21); } //--------------------------------------------------------------------------------------------------------------------------------------// //Get the HTU21D user register. Returns 8 bit register. uint8_t htu21d::getUserReg() { - -#ifdef RTOS_H - MutexI2cWait.lock(); -#endif - +#if defined HTU21Di2cLOWLEVEL int htu21 = 0; uint8_t htu21data = 0; _i2c.start(); @@ -76,12 +70,16 @@ htu21data = _i2c.read(0); _i2c.stop(); } - -#ifdef RTOS_H - MutexI2cWait.unlock(); + return(htu21data); +#else + htuBuffer[0] = HTU21DREADUSER; + _i2c.write(HTU21Di2cWRITE, htuBuffer, 1, true); + if(!(_i2c.read(HTU21Di2cREAD, htuBuffer, 1, false))) { + return(htuBuffer[0]); + } else { + return(0); + } #endif - - return(htu21data); } //--------------------------------------------------------------------------------------------------------------------------------------// @@ -90,11 +88,7 @@ int htu21d::heaterOn() { uint8_t htu21data = htu21d::getUserReg(); htu21data |= HTU21DHEATER; - -#ifdef RTOS_H - MutexI2cWait.lock(); -#endif - +#if defined HTU21Di2cLOWLEVEL int htu21 = 0; _i2c.start(); htu21 = _i2c.write(HTU21Di2cWRITE); //i2c, 1 = ack @@ -103,12 +97,12 @@ htu21 = _i2c.write(htu21data); _i2c.stop(); } - -#ifdef RTOS_H - MutexI2cWait.unlock(); + return(htu21); +#else + htuBuffer[0] = HTU21DWRITEUSER; + htuBuffer[1] = htu21data; + return(_i2c.write(HTU21Di2cWRITE, htuBuffer, 2, false)); #endif - - return(htu21); } //--------------------------------------------------------------------------------------------------------------------------------------// @@ -117,11 +111,7 @@ int htu21d::heaterOff() { uint8_t htu21data = htu21d::getUserReg(); htu21data &= ~HTU21DHEATER; - -#ifdef RTOS_H - MutexI2cWait.lock(); -#endif - +#if defined HTU21Di2cLOWLEVEL int htu21 = 0; _i2c.start(); htu21 = _i2c.write(HTU21Di2cWRITE); //i2c, 1 = ack @@ -130,12 +120,13 @@ htu21 = _i2c.write(htu21data); _i2c.stop(); } - -#ifdef RTOS_H - MutexI2cWait.unlock(); + return(htu21); +#else + htuBuffer[0] = HTU21DWRITEUSER; + htuBuffer[1] = htu21data; + return(_i2c.write(HTU21Di2cWRITE, htuBuffer, 2, false)); #endif - return(htu21); } //--------------------------------------------------------------------------------------------------------------------------------------// @@ -154,27 +145,17 @@ //NOTE: Use non-hold commands uint16_t htu21d::getData(uint8_t reg) { - int htu21 = 0; //ACK flag int htu21cnt = 0; //number of NACKs before ACK or timeout +#if defined HTU21Di2cLOWLEVEL uint16_t htu21data = 0; //returned data - -#ifdef RTOS_H - MutexI2cWait.lock(); -#endif + int htu21 = 0; //ACK flag _i2c.start(); htu21 = _i2c.write(HTU21Di2cWRITE); _i2c.write(reg); //read temp, no hold _i2c.stop(); -#ifdef RTOS_H - MutexI2cWait.unlock(); -#endif - if(htu21 == 0) return 0; //HTU21T not responding do { htu21cnt++; -#ifdef RTOS_H - MutexI2cWait.lock(); -#endif _i2c.start(); htu21 = _i2c.write(HTU21Di2cREAD); if(htu21 == 1) { @@ -182,16 +163,23 @@ htu21data |= _i2c.read(0) & 0xFC; _i2c.stop(); } -#ifdef RTOS_H - MutexI2cWait.unlock(); //free up the I2C bus - Thread::wait(1); //allow other RTOS functions to sneak in -#else wait_us(1000); -#endif } while((htu21cnt < 100) && (htu21 == 0)); //htu21cnt takes 55 to get temp, 16 for humidity (at 1mS loops) if(htu21 == 0) return 0; //HTU21D ACK response timed out return(htu21data); //return 14 bit value +#else + htuBuffer[0] = reg; + _i2c.write(HTU21Di2cWRITE, htuBuffer, 1, false); + do { + htu21cnt++; + if(!(_i2c.read(HTU21Di2cREAD, htuBuffer, 2, false))) { + return((htuBuffer[0] << 8) | htuBuffer[1]); + } + wait_us(1000); + } while(htu21cnt < 100); + return 0; +#endif } //--------------------------------------------------------------------------------------------------------------------------------------// @@ -254,12 +242,8 @@ //should return 0x4854 00xx xxxx 32xx void htu21d::getSNReg() { - -#ifdef RTOS_H - MutexI2cWait.lock(); -#endif - //get 16 bit SNC register, 8 bit SNC-CRC, 16 bit SNA register, 8 bit SNA-CRC +#if defined HTU21Di2cLOWLEVEL int htu21 = 0; _i2c.start(); htu21 = _i2c.write(HTU21Di2cWRITE); //i2c, 1 = ack @@ -275,9 +259,25 @@ HTU21sn.HTU21D_sna |= _i2c.read(1); HTU21sn.HTU21D_crca = _i2c.read(0); _i2c.stop(); + } else { + HTU21sn.HTU21D_snc = HTU21sn.HTU21D_crcc = HTU21sn.HTU21D_sna = HTU21sn.HTU21D_crca = 0; } +#else + htuBuffer[0] = HTU21SNAC1; + htuBuffer[1] = HTU21SNAC2; + _i2c.write(HTU21Di2cWRITE, htuBuffer, 2, true); + if(!(_i2c.read(HTU21Di2cREAD, htuBuffer, 6, false))) { + HTU21sn.HTU21D_snc = (htuBuffer[0] << 8) | htuBuffer[1]; + HTU21sn.HTU21D_crcc = htuBuffer[2]; + HTU21sn.HTU21D_sna = (htuBuffer[3] << 8) | htuBuffer[4]; + HTU21sn.HTU21D_crca = htuBuffer[5]; + } else { + HTU21sn.HTU21D_snc = HTU21sn.HTU21D_crcc = HTU21sn.HTU21D_sna = HTU21sn.HTU21D_crca = 0; + } +#endif //get 32 bit SNB register, 32 bit SNB-CRC - regs are intermixed +#if defined HTU21Di2cLOWLEVEL htu21 = 0; _i2c.start(); htu21 = _i2c.write(HTU21Di2cWRITE); //i2c, 1 = ack @@ -295,11 +295,19 @@ HTU21sn.HTU21D_snb |= _i2c.read(1); HTU21sn.HTU21D_crcb |= _i2c.read(0); _i2c.stop(); + } else { + HTU21sn.HTU21D_snb = HTU21sn.HTU21D_crcb = 0; } - -#ifdef RTOS_H - MutexI2cWait.unlock(); +#else + htuBuffer[0] = HTU21SNB1; + htuBuffer[1] = HTU21SNB2; + _i2c.write(HTU21Di2cWRITE, htuBuffer, 2, true); + if(!(_i2c.read(HTU21Di2cREAD, htuBuffer, 8, false))) { + HTU21sn.HTU21D_snb = (htuBuffer[0] << 24) | (htuBuffer[2] << 16) | (htuBuffer[4] << 8) | htuBuffer[6]; + HTU21sn.HTU21D_crcb = (htuBuffer[1] << 24) | (htuBuffer[3] << 16) | (htuBuffer[5] << 8) | htuBuffer[7]; + } else { + HTU21sn.HTU21D_snb = HTU21sn.HTU21D_crcb = 0; + } #endif - }
diff -r 8fbe84ed61e6 -r 5c0f8e91d319 htu21d.h --- a/htu21d.h Thu May 22 18:48:46 2014 +0000 +++ b/htu21d.h Thu Apr 30 00:34:03 2015 +0000 @@ -9,6 +9,13 @@ #include "mbed.h" +#if(defined(TARGET_KL25Z) )//|| defined(TARGET_K64F)) + + #define HTU21Di2cLOWLEVEL 1 //if the use of low-level I2C routines is needed + #warning "HTU21D using low level I2C routines" + +#endif + //Defines for HTU21D #define HTU21Di2cWRITE 0x80 #define HTU21Di2cREAD 0x81 @@ -249,6 +256,9 @@ * * @return --none-- */ +#if not defined HTU21Di2cLOWLEVEL +char htuBuffer[8]; +#endif void getSNReg(); double theTempIs; double theHumIs;