Interrupt driven DHT11/DHT22 library, port of Arduino idDHTLib (https://github.com/niesteszeck/idDHTLib)

Dependents:   NewDHT11Test

Revision:
0:53913db38502
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/idDHTLib.cpp	Tue Nov 19 19:36:47 2013 +0000
@@ -0,0 +1,218 @@
+/*
+    FILE:       idDHTLib.cpp
+    VERSION:    0.0.3
+    PURPOSE:    Interrupt driven Lib for DHT11 and DHT22 for mbed.
+    LICENCE:    GPL v3 (http://www.gnu.org/licenses/gpl.html)
+    DATASHEET: http://www.micro4you.com/files/sensor/DHT11.pdf
+    DATASHEET: http://www.adafruit.com/datasheets/DHT22.pdf
+    
+    Based on idDHT11 library: https://github.com/niesteszeck/idDHT11
+    Based on DHTLib library: http://playground.arduino.cc/Main/DHTLib
+    Based on code proposed: http://forum.arduino.cc/index.php?PHPSESSID=j6n105kl2h07nbj72ac4vbh4s5&topic=175356.0
+    Mbed port of Arduino library: https://github.com/niesteszeck/idDHTLib
+    
+    Changelog:
+        v 0.0.1
+            fork from idDHT11 lib
+            change names to idDHTLib
+            added DHT22 functionality
+        v 0.0.2
+            Optimization on shift var (pylon from Arduino Forum)
+        v 0.0.3
+            Timing correction to finally work properly on DHT22
+            (Dessimat0r from Arduino forum)
+ */
+
+#include "idDHTLib.h"
+#define DEBUG_idDHTLIB
+
+idDHTLib::idDHTLib(PinName pin, void (*callback_wrapper)()): inOut(pin), intIn(pin) {
+    init(pin,callback_wrapper);
+}
+
+void idDHTLib::init(PinName pin,  void (*callback_wrapper) ()) {
+    this->pin = pin;
+    this->isrCallback_wrapper = callback_wrapper;
+    hum = 0;
+    temp = 0;
+    inOut.output();
+    inOut = 1;
+    state = STOPPED;
+    status = IDDHTLIB_ERROR_NOTSTARTED;
+}
+
+int idDHTLib::acquire() {
+    if (state == STOPPED || state == ACQUIRED) {
+        
+        //set the state machine for interruptions analisis of the signal
+        state = RESPONSE;
+        
+        // EMPTY BUFFER and vars
+        for (int i=0; i< 5; i++) bits[i] = 0;
+        cnt = 7;
+        idx = 0;
+        hum = 0;
+        temp = 0;
+    
+        // REQUEST SAMPLE
+        inOut.output();
+        inOut = 0;
+        wait_ms(18);
+        inOut = 1;
+        wait_us(25);
+        inOut.input();
+        t.start();
+ 
+        handler = intIn.fall(isrCallback_wrapper);
+        
+        return IDDHTLIB_ACQUIRING;
+    } else
+        return IDDHTLIB_ERROR_ACQUIRING;
+}
+int idDHTLib::acquireAndWait() {
+    acquire();
+    while(acquiring())
+        ;
+    return getStatus();
+}
+void idDHTLib::dht11Callback() {
+    isrCallback(false);
+}
+void idDHTLib::dht22Callback() {
+    isrCallback(true);
+}
+
+void idDHTLib::isrCallback(bool dht22) {
+    int delta = t.read_us();
+    t.reset();
+    if (delta>6000) {
+        status = IDDHTLIB_ERROR_TIMEOUT;
+        state = STOPPED;
+        intIn.fall_remove(handler);
+        return;
+    }
+    switch(state) {
+        case RESPONSE:
+            if(delta<25){
+                break; //do nothing, it started the response signal
+            } if(125<delta && delta<190) {
+                state = DATA;
+            } else {
+                intIn.fall_remove(handler);
+                status = IDDHTLIB_ERROR_TIMEOUT;
+                state = STOPPED;
+            }
+            break;
+        case DATA:
+            if(60<delta && delta<145) { //valid in timing
+                bits[idx] <<= 1; //shift the data
+                if(delta>100) //is a one
+                    bits[idx] |= 1;
+                if (cnt == 0) {  // when we have fulfilled the byte, go to the next
+                        cnt = 7;    // restart at MSB
+                        if(++idx == 5) { // go to next byte; when we have got 5 bytes, stop.
+                            intIn.fall_remove(handler);
+                            // WRITE TO RIGHT VARS 
+                            uint8_t sum;
+                            if (dht22) {
+                                hum = (bits[0] << 8 |  bits[1]) * 0.1;
+                                temp = (bits[2] & 0x80 ?
+                                    -(bits[2] & 0x7F << 8 | bits[3]) :
+                                    (bits[2] << 8 | bits[3]))
+                                * 0.1;
+                                sum = bits[0] + bits[1] + bits[2] + bits[3];
+                                printf("DHT22 Bits: %02d %02d %02d %02d %02d sum=%02d\r\n", bits[0],bits[1],bits[2],bits[3],bits[4],sum&0xff);
+                            
+                            } else {
+                                hum    = bits[0]; 
+                                // as bits[1] and bits[3] are always zero they are omitted in formulas.
+                                temp = bits[2];
+                                sum = bits[0] + bits[2];
+                            }  
+                            if (bits[4] != (sum&0xFF)) {
+                                status = IDDHTLIB_ERROR_CHECKSUM;
+                                state = STOPPED;
+                            } else {
+                                status = IDDHTLIB_OK;
+                                state = ACQUIRED;
+                            }
+                            break;
+                        }
+                } else cnt--;
+            } else if(delta<10) {
+                intIn.fall_remove(handler);
+                status = IDDHTLIB_ERROR_DELTA;
+                state = STOPPED;
+            } else {
+                intIn.fall_remove(handler);
+                status = IDDHTLIB_ERROR_TIMEOUT;
+                state = STOPPED;
+            }
+            break;
+        default:
+            break;
+    }
+}
+bool idDHTLib::acquiring() {  
+    if (state != ACQUIRED && state != STOPPED) {   
+        int delta = t.read_us();
+        if (delta>6000) {
+            status = IDDHTLIB_ERROR_TIMEOUT;
+            state = STOPPED;
+            intIn.fall_remove(handler);
+            return false;
+        }    
+        return true;
+    }
+    return false;
+}
+int idDHTLib::getStatus() {
+    return status;
+}
+float idDHTLib::getCelsius() {
+    IDDHTLIB_CHECK_STATE;
+    return temp;
+}
+
+float idDHTLib::getHumidity() {
+    IDDHTLIB_CHECK_STATE;
+    return hum;
+}
+
+float idDHTLib::getFahrenheit() {
+    IDDHTLIB_CHECK_STATE;
+    return temp * 1.8 + 32;
+}
+
+float idDHTLib::getKelvin() {
+    IDDHTLIB_CHECK_STATE;
+    return temp + 273.15;
+}
+
+// delta max = 0.6544 wrt dewPoint()
+// 5x faster than dewPoint()
+// reference: http://en.wikipedia.org/wiki/Dew_point
+double idDHTLib::getDewPoint() {
+    IDDHTLIB_CHECK_STATE;
+    double a = 17.271;
+    double b = 237.7;
+    double temp_ = (a * (double) temp) / (b + (double) temp) + log( (double) hum/100);
+    double Td = (b * temp_) / (a - temp_);
+    return Td;
+    
+}
+// dewPoint function NOAA
+// reference: http://wahiduddin.net/calc/density_algorithms.htm 
+double idDHTLib::getDewPointSlow() {
+    IDDHTLIB_CHECK_STATE;
+    double A0= 373.15/(273.15 + (double) temp);
+    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) * (double) hum;
+    double T = log(VP/0.61078);   // temp var
+    return (241.88 * T) / (17.558-T);
+}
+// EOF
\ No newline at end of file