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.

Dependents:   BLE_soil_humidity

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.

Files at this revision

API Documentation at this revision

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
--- 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
-
 }
 
--- 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;