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 May 15 19:12:11 2014 +0000
Parent:
0:2dab43acb3a4
Child:
2:8fbe84ed61e6
Commit message:
Added serial number access structure. Cleaned up documentation.

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	Wed May 14 00:31:30 2014 +0000
+++ b/htu21d.cpp	Thu May 15 19:12:11 2014 +0000
@@ -1,7 +1,9 @@
 /**
-HTU21D driver for mbed.  Includes RTOS hooks if RTOS is detected during compile
+HTU21D / HPP828E031 driver for mbed.
+- Includes RTOS hooks if RTOS is detected during compile.
 Author: Kevin Braun
 **/
+
 #include "htu21d.h"
 
 #ifdef RTOS_H
@@ -12,11 +14,15 @@
 //Contstructor
 
 htu21d::htu21d(PinName sda, PinName scl) : _i2c(sda, scl) {
-//    _i2c = new I2C(sda, scl);
+    _i2c.frequency(400000);
+}
+
+htu21d::htu21d(PinName sda, PinName scl, int i2cFrequency) : _i2c(sda, scl) {
+    _i2c.frequency(i2cFrequency);
 }
 
 //--------------------------------------------------------------------------------------------------------------------------------------//
-//De-contstructor
+//Destructor
 
 htu21d::~htu21d() {
 }
@@ -36,9 +42,10 @@
     if(htu21 == 1) {
         _i2c.write(HTU21DRESET);            //soft reset, must wait 15mS
         _i2c.stop();
+        wait_ms(16);                        //must wait a least 15mS for reset to finish
+        htu21d::getSNReg();                 //go load up the s/n registers
     }
-    wait_ms(16);                            //must wait a least 15mS for reset to finish
-    
+
 #ifdef RTOS_H
     MutexI2cWait.unlock();
 #endif
@@ -166,7 +173,7 @@
             _i2c.stop();
         }
         wait_us(50);
-    } while((htu21cnt < 1000) && (htu21 == 0)); //htu21cnt takes 510 to get temp, 160 for humidity
+    } while((htu21cnt < 10000) && (htu21 == 0)); //htu21cnt takes 510 to get temp, 160 for humidity
  
 #ifdef RTOS_H
     MutexI2cWait.unlock();
@@ -232,3 +239,58 @@
     double h21DtzD = (h21DtzB * h21DtzC) / (h21DtzA - h21DtzC);
     return (h21DtzD);
 }
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+//Get the HTU21D serial number registers. Returns 64 bit register.
+//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
+    int htu21 = 0;
+    _i2c.start();
+    htu21 = _i2c.write(HTU21Di2cWRITE);     //i2c, 1 = ack
+    if(htu21 == 1) {
+        _i2c.write(HTU21SNAC1);
+        _i2c.write(HTU21SNAC2);
+        _i2c.start();
+        htu21 = _i2c.write(HTU21Di2cREAD);
+        HTU21sn.HTU21D_snc = _i2c.read(1) << 8;
+        HTU21sn.HTU21D_snc |= _i2c.read(1);
+        HTU21sn.HTU21D_crcc = _i2c.read(1);
+        HTU21sn.HTU21D_sna = _i2c.read(1) << 8;
+        HTU21sn.HTU21D_sna |= _i2c.read(1);
+        HTU21sn.HTU21D_crca = _i2c.read(0);
+        _i2c.stop();
+    }
+    
+    //get 32 bit SNB register, 32 bit SNB-CRC - regs are intermixed
+    htu21 = 0;
+    _i2c.start();
+    htu21 = _i2c.write(HTU21Di2cWRITE);     //i2c, 1 = ack
+    if(htu21 == 1) {
+        _i2c.write(HTU21SNB1);
+        _i2c.write(HTU21SNB2);
+        _i2c.start();
+        htu21 = _i2c.write(HTU21Di2cREAD);
+        HTU21sn.HTU21D_snb = _i2c.read(1) << 24;
+        HTU21sn.HTU21D_crcb = _i2c.read(1) << 24;
+        HTU21sn.HTU21D_snb |= _i2c.read(1) << 16;
+        HTU21sn.HTU21D_crcb |= _i2c.read(1) << 16;
+        HTU21sn.HTU21D_snb |= _i2c.read(1) << 8;
+        HTU21sn.HTU21D_crcb |= _i2c.read(1) << 8;
+        HTU21sn.HTU21D_snb |= _i2c.read(1);
+        HTU21sn.HTU21D_crcb |= _i2c.read(0);
+        _i2c.stop();
+    }
+    
+#ifdef RTOS_H
+    MutexI2cWait.unlock();
+#endif
+
+}
+
--- a/htu21d.h	Wed May 14 00:31:30 2014 +0000
+++ b/htu21d.h	Thu May 15 19:12:11 2014 +0000
@@ -1,5 +1,8 @@
 /**
- */
+HTU21D / HPP828E031 driver for mbed.
+- Includes RTOS hooks if RTOS is detected during compile.
+Author: Kevin Braun
+ **/
 
 #ifndef HTU21D_H
 #define HTU21D_H
@@ -16,116 +19,239 @@
 #define HTU21DhumNOHOLD     0xF5
 #define HTU21DRESET         0xFE
 
+#define HTU21SNAC1          0xFC
+#define HTU21SNAC2          0xC9
+#define HTU21SNB1           0xFA
+#define HTU21SNB2           0x0F
+
 #define HTU21DHEATER        0x04
 
 
-/**
- * Honeywell HTU21D digital humidity and temperature sensor.
- */
+    /**
+    * measurement specialties / Honeywell HTU21D digital humidity and temperature sensor.
+    * - Web site: http://www.meas-spec.com  
+    * - Part Number: HPP828E031
+    * - HTU21D = +-3% rh error at 55%
+    * - HTU20D = +-5% rh error at 55%
+    * - Main code generated from datasheet dated October 2013
+    * - Serial number code generated from App Note "HTU2X Serial Number Reading", dated Februrary 2014
+    * - No checksum checking is performed in this code
+    *
+    * @code
+    * //Tested on FRDM-K64F
+    *
+    * #include "mbed.h"
+    * #include "htu21d.h"
+    *
+    * #define SDA     PTE25 
+    * #define SCL     PTE24
+    *
+    * Serial pc(USBTX, USBRX);                  //local terminal
+    * htu21d htu(SDA, SCL);                     //Temp Hum || sda, scl
+    *
+    * float H21Temp = 0.0;                      //Temperture from HTU21D
+    * float H21Hum = 0.0;                       //Humidity from HTU21D
+    * float H21Dew = 0.0;                       //Dew Point from HTU21D
+    *
+    * //Note: If RTOS is used, Mutex for I2C must be initialized
+    * #ifdef RTOS_H
+    * Mutex MutexI2cWait;
+    * #endif
+    *
+    * int main() {
+    *     pc.baud(230400);                        //local terminal baud
+    *     pc.printf("\r\n\r\nK64F_HTU21D basic operation\r\n"); 
+    * 
+    *     //initialize the HTU21D
+    *     int htu21 = htu.softReset();
+    *     if(htu21 == 0) {
+    *         pc.printf(" - HTU21D broken...\r\n");
+    *     } else {
+    *         uint8_t HTU21DuserReg = htu.getUserReg();
+    *         pc.printf("HTU21D UserReg: 0x%02x   SN: 0x%04x %08x %04x\r\n", 
+    *                   HTU21DuserReg, htu.HTU21sn.HTU21D_sna, htu.HTU21sn.HTU21D_snb, htu.HTU21sn.HTU21D_snc);
+    *     }
+    * 
+    *     while(true) {
+    *         //get humidity, temperature and dew point from HTU21D
+    *         if(htu21 == 1) {    //if HTU21D didn't initialize, don't access HTU21D anymore
+    *             H21Hum = htu.getHum();
+    *             if((double)H21Hum == 255.0) pc.printf("\r\n*** HTU21D Hum error!!\r\n");
+    *             H21Temp = htu.getTemp();
+    *             if((double)H21Temp == 255.0) pc.printf("\r\n*** HTU21D Temp error!!\r\n");
+    *             H21Dew = htu.getDewPtFast();
+    *         }
+    *         pc.printf("Temp: %7.2f C %7.2f F   Hum: %4.1f %%   DewPt: %7.2f C\r\n", H21Temp, H21Hum, H21Dew);
+    *         wait(1.0);
+    *     }
+    * }
+    * @endcode
+    **/
 class htu21d {
 
 public:
     /**
-     * Constructor.
+     * Constructor
+     * - Fixed at I2C address 0x80
+     * - I2C speed set to 400000
      *
-     * @param sda and scl, mbed I2C interface pins.
+     * @param PinName sda and scl, mbed I2C interface pins
      */
     htu21d(PinName sda, PinName scl);
     /**
-     * De-constructor.
+     * Constructor
+     * - Fixed at I2C address 0x80
+     * - I2C speed set by user
      *
-     * @param --none--.
+     * @param PinName sda and scl, mbed I2C interface pins 
+     * @param int I2C frequency
+     */
+    htu21d(PinName sda, PinName scl, int i2cFrequency);
+    /**
+     * Destructor
+     *
+     * @param --none--
      */
     ~htu21d();
     /**
-     * Get HTU21D Temperature.
+     * Reset the HTU21D chip
+     * - Waits 15mS before exiting, allowing the chip reset to finish
+     * - Executes getSNReg() which loads up HTU21D serial number structure
      * 
-     * @param --none--.
+     * @param --none-- NOTE: run softReset() once at initialization time
      *
-     * @return success / failure of HTU21D i2c access. 1 = ok, 0 = error.
+     * @return success / failure of HTU21D i2c access. 1 = ok, 0 = error
     */
     int softReset();
     /**
-     * Get HTU21D user register.
+     * Get HTU21D user register
      * 
-     * @param --none--.
+     * @param --none--
      *
-     * @return success / failure of HTU21D i2c access. 1 = ok, 0 = error.
+     * @return 8 bit user register value
     */
     uint8_t getUserReg();
     /**
-     * Turn ON the heater in the HTU21D.
+     * Turn ON the heater on the HTU21D
      * 
-     * @param --none--.
+     * @param --none--
      *
-     * @return success / failure of HTU21D i2c access. 1 = ok, 0 = error.
+     * @return success / failure of HTU21D i2c access. 1 = ok, 0 = error
     */
     int heaterOn();
     /**
-     * Turn OFF the heater in the HTU21D.
+     * Turn OFF the heater on the HTU21D
      * 
-     * @param --none--.
+     * @param --none--
      *
-     * @return --none--.
+     * @return success / failure of HTU21D i2c access. 1 = ok, 0 = error
     */
     int heaterOff();
     /**
-     * Get heater on/off status in the HTU21D.
+     * Get heater on/off status of the HTU21D
      * 
-     * @param --none--.
+     * @param --none--
      *
-     * @return 4 = on, 0 = 0ff.
+     * @return 0x04 = on, 0 = off
     */
     uint8_t getHeater();
     /**
-     * Do a reset on the HTU21D.
+     * Get HTU21D Temperature
      * 
-     * @param --none--.
+     * @param --none--
      *
-     * @return float of Temperature in degrees C.  255.0 if error.
+     * @return float of Temperature in degrees C.  255.0 if error
     */
     float getTemp();
     /**
-     * Get HTU21D Humidity.
+     * Get HTU21D Humidity
      * 
-     * @param --none--.
+     * @param --none--
      *
-     * @return float of Humidity in percentage.  255.0 if error.
+     * @return float of Humidity in percentage.  255.0 if error
     */
     float getHum();
     /**
-     * Claculate the Dew Point.
+     * Calculate the Dew Point
      * 
-     * @param MUST run getTemp and getHum first!!
+     * @param --none-- NOTE: You MUST run getTemp() and getHum() first!!
      *
-     * @return float of Dew Point.
+     * @return float of Dew Point
     */
     float getDewPt();
     /**
-     * Claculate the Dew Point. 5x faster than getDewPt().
+     * Calculate the Dew Point fast
+     * - 5x faster than getDewPt()
+     * - slightly less accurate than getDewPt()
      * 
-     * @param MUST run getTemp and getHum first!!
+     * @param --none-- NOTE: You MUST run getTemp() and getHum() first!!
      *
-     * @return float of Dew Point.
+     * @return float of Dew Point
     */
     float getDewPtFast();
-
- 
+    /**
+     * Structure to access HTU21D's serial number 
+     * - HTU21D_sna is the hi  16 bit word of the s/n, always is 0x4854
+     * - HTU21D_snb is the mid 32 bit word of the s/n, 0x00--------
+     * - HTU21D_snc is the low 16 bit word of the s/n, 0x32--
+     * - The complete 64 bit s/n value is: 0x48 54 00 -- -- -- 32 --
+     * - The numbers shown are fixed fields
+     * - The '-' numbers are variable
+     * - For reference, the CRC values for the s/n are included
+    */    
+    struct HTU21snStruct {
+        uint16_t HTU21D_sna;            /**< Highest order 16 bit word of SN
+                                            - Value always = 0x4854
+                                            */
+        uint32_t HTU21D_snb;            /**< Middle order 32 bit word of SN
+                                            - Value = 0x00--------
+                                            - Highest byte always = 0x00
+                                            - Lower 3 bytes are variable
+                                            */
+        uint16_t HTU21D_snc;            /**< Lowest order 16 bit word of SN
+                                            - Value = 0x32--
+                                            - Highest byte always = 0x32
+                                            - Lowest byte is variable
+                                            */
+        uint8_t HTU21D_crca;            /**< Single byte checksum from HTU21D_sna
+                                            */  
+        uint32_t HTU21D_crcb;           /**< Four byte checksum from HTU21D_snb
+                                            */
+        uint8_t HTU21D_crcc;            /**< Single byte checksum from HTU21D_snc
+                                            */
+        HTU21snStruct() {
+            HTU21D_sna = 0;
+            HTU21D_snb = 0;
+            HTU21D_snc = 0;
+            HTU21D_crca = 0;
+            HTU21D_crcb = 0;
+            HTU21D_crcc = 0;
+        }
+    } HTU21sn;
 
 private:
     I2C _i2c;
     /**
-     * I2C access for getting raw Temperature and Humidity data.
+     * I2C access for getting raw Temperature and Humidity data
      * 
-     * @param 8 bit HTU21D register to get data from. Must use non-blocking regs.
+     * @param 8 bit HTU21D register to get data from. Must use non-blocking regs
      *
-     * @return 16 bit raw i2c data, ANDed to 14 bits 0xFFFC. 0000 if error.
+     * @return 16 bit raw i2c data, ANDed to 14 bits 0xFFFC. 0000 if error
     */
     uint16_t getData(uint8_t reg);
+    /**
+     * Get the HTU21D's serial number. 
+     * - Number returned is 0x4854 00-- ---- 32--
+     * - The numbers shown are fixed fields
+     * - The '-' numbers are variable
+     * 
+     * @param --none--
+     *
+     * @return --none--
+    */
+    void getSNReg();
     double theTempIs;
     double theHumIs;
-    float getTrash();
-
 };
 
 #endif