htu21d_for_weather_shield

Dependents:   SPARKFUN_WEATHER_SHIELD

Fork of htu21d by Kevin Braun

Revision:
0:2dab43acb3a4
Child:
1:d3ed713f8354
diff -r 000000000000 -r 2dab43acb3a4 htu21d.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/htu21d.cpp	Wed May 14 00:31:30 2014 +0000
@@ -0,0 +1,234 @@
+/**
+HTU21D driver for mbed.  Includes RTOS hooks if RTOS is detected during compile
+Author: Kevin Braun
+**/
+#include "htu21d.h"
+
+#ifdef RTOS_H
+extern Mutex MutexI2cWait;
+#endif
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+//Contstructor
+
+htu21d::htu21d(PinName sda, PinName scl) : _i2c(sda, scl) {
+//    _i2c = new I2C(sda, scl);
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+//De-contstructor
+
+htu21d::~htu21d() {
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+//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;
+    _i2c.start();
+    htu21 = _i2c.write(HTU21Di2cWRITE);     //i2c, 1 = ack
+    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
+    
+#ifdef RTOS_H
+    MutexI2cWait.unlock();
+#endif
+
+    return(htu21);
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+//Get the HTU21D user register. Returns 8 bit register.
+
+uint8_t htu21d::getUserReg() {
+    
+#ifdef RTOS_H
+    MutexI2cWait.lock();
+#endif
+
+    int htu21 = 0;
+    uint8_t htu21data = 0;
+    _i2c.start();
+    htu21 = _i2c.write(HTU21Di2cWRITE);     //i2c, 1 = ack
+    if(htu21 == 1) {
+        _i2c.write(HTU21DREADUSER);
+        _i2c.start();
+        htu21 = _i2c.write(HTU21Di2cREAD);
+        htu21data = _i2c.read(0);
+        _i2c.stop();
+    }
+    
+#ifdef RTOS_H
+    MutexI2cWait.unlock();
+#endif
+
+    return(htu21data);
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+//Turn ON the heater the HTU21D user register. 
+
+int htu21d::heaterOn() {
+    uint8_t htu21data = htu21d::getUserReg();
+    htu21data |= HTU21DHEATER;
+    
+#ifdef RTOS_H
+    MutexI2cWait.lock();
+#endif
+
+    int htu21 = 0;
+    _i2c.start();
+    htu21 = _i2c.write(HTU21Di2cWRITE);     //i2c, 1 = ack
+    if(htu21 == 1) {
+        _i2c.write(HTU21DWRITEUSER);
+        htu21 = _i2c.write(htu21data);
+        _i2c.stop();
+    }
+    
+#ifdef RTOS_H
+    MutexI2cWait.unlock();
+#endif
+
+    return(htu21);
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+//Turn OFF the heater the HTU21D user register. 
+
+int htu21d::heaterOff() {
+    uint8_t htu21data = htu21d::getUserReg();
+    htu21data &= ~HTU21DHEATER;
+    
+#ifdef RTOS_H
+    MutexI2cWait.lock();
+#endif
+
+    int htu21 = 0;
+    _i2c.start();
+    htu21 = _i2c.write(HTU21Di2cWRITE);     //i2c, 1 = ack
+    if(htu21 == 1) {
+        _i2c.write(HTU21DWRITEUSER);
+        htu21 = _i2c.write(htu21data);
+        _i2c.stop();
+    }
+    
+#ifdef RTOS_H
+    MutexI2cWait.unlock();
+#endif
+
+    return(htu21);
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+//Get the status of the heater the HTU21D user register. 0 = off, 4 = on.
+
+uint8_t htu21d::getHeater() {
+    uint8_t htu21data = htu21d::getUserReg();
+    htu21data &= HTU21DHEATER;
+    return(htu21data);
+}
+    
+//--------------------------------------------------------------------------------------------------------------------------------------//
+//generic routine to get temp or humidity from HTU21D. 
+//Returns 14 bits of data (anded 0xFFFC) or 0000 if i2c timeout occurs.
+//After a read temp or humidity command, HTU21D responds with NACKs until data is ready.
+//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 
+    uint16_t htu21data = 0;     //returned data
+
+#ifdef RTOS_H
+    MutexI2cWait.lock();
+#endif
+
+    _i2c.start();
+    htu21 = _i2c.write(HTU21Di2cWRITE);
+    _i2c.write(reg);            //read temp, no hold
+    if(htu21 == 0) return 0;    //HTU21T not responding
+    do {
+        htu21cnt++;
+        _i2c.start();
+        htu21 = _i2c.write(HTU21Di2cREAD);
+        if(htu21 == 1) {
+            htu21data = _i2c.read(1) << 8;
+            htu21data |= _i2c.read(0) & 0xFC;
+            _i2c.stop();
+        }
+        wait_us(50);
+    } while((htu21cnt < 1000) && (htu21 == 0)); //htu21cnt takes 510 to get temp, 160 for humidity
+ 
+#ifdef RTOS_H
+    MutexI2cWait.unlock();
+#endif
+
+    if(htu21 == 0) return 0;    //HTU21D ACK response timed out
+    return(htu21data);          //return 14 bit value
+}
+
+double theTempIs = 0.0;
+double theHumIs = 0.0;
+//--------------------------------------------------------------------------------------------------------------------------------------//
+//get temperature from HTU21D in degrees C. Returns with 255.0 if HTU21D had timed out.
+
+float htu21d::getTemp() {
+    uint16_t getData = htu21d::getData(HTU21DtempNOHOLD);
+    if (getData == 0) return(255.0);                        //return with error
+    double tempData = (double)getData / 65536.0;
+    theTempIs = -46.85 + (175.72 * tempData);
+    return(theTempIs);
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+//get humidity from HTU21D in percentage. Returns with 255.0 if HTU21D had timed out.
+
+float htu21d::getHum() {
+    uint16_t getData = htu21d::getData(HTU21DhumNOHOLD);
+    if (getData == 0) return(255.0);                        //return with error
+    double tempData = (double)getData / 65536.0;
+    theHumIs = -6.0 + (125.0 * tempData);
+    return(theHumIs);
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+//Calculate the Dew Point from getTemp and getHum. User must first execute both getTemp and getHum for an accurate result.
+//Calculations come from DHT library
+/*  Copyright (C) Wim De Roeve
+ *                based on DHT22 sensor library by HO WING KIT
+ *                Arduino DHT11 library
+*/
+
+float htu21d::getDewPt() {
+    // dewPoint function NOAA
+    // reference: http://wahiduddin.net/calc/density_algorithms.htm    
+    double A0= 373.15/(273.15 + (double)theTempIs);
+    double SUM = -7.90298 * (A0-1);
+    SUM += 5.02808 * log10(A0);
+    SUM += -1.3816e-7 * (pow(10, (11.344*(1-1/A0)))-1) ;
+    SUM += 8.1328e-3 * (pow(10,(-3.49149*(A0-1)))-1) ;
+    SUM += log10(1013.246);
+    double VP = pow(10, SUM-3) * theHumIs;
+    double T = log(VP/0.61078);   // temp var
+    return (241.88 * T) / (17.558-T);
+}
+
+float htu21d::getDewPtFast() {
+    // delta max = 0.6544 wrt dewPoint()
+    // 5x faster than dewPoint()
+    // reference: http://en.wikipedia.org/wiki/Dew_point
+    double h21DtzA = 17.271;
+    double h21DtzB = 237.7;
+    double h21DtzC = (h21DtzA * theTempIs) / (h21DtzB + theTempIs) + log(theHumIs/100);
+    double h21DtzD = (h21DtzB * h21DtzC) / (h21DtzA - h21DtzC);
+    return (h21DtzD);
+}