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

Dependents:   NewDHT11Test

Files at this revision

API Documentation at this revision

Comitter:
kfigiela
Date:
Tue Nov 19 19:36:47 2013 +0000
Commit message:
DHT11 and DHT22 working

Changed in this revision

idDHTLib.cpp Show annotated file Show diff for this revision Revisions of this file
idDHTLib.h Show annotated file Show diff for this revision Revisions of this file
--- /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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/idDHTLib.h	Tue Nov 19 19:36:47 2013 +0000
@@ -0,0 +1,87 @@
+/*
+    FILE:       idDHTLib.h
+    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)
+ */
+
+#ifndef idDHTLib_H__
+#define idDHTLib_H__
+
+#define IDDHTLIB_VERSION "0.0.3"
+#include "mbed.h"
+
+// state codes
+#define IDDHTLIB_OK         0
+#define IDDHTLIB_ACQUIRING      1
+#define IDDHTLIB_ACQUIRED       2
+#define IDDHTLIB_RESPONSE_OK        3
+
+// error codes
+#define IDDHTLIB_ERROR_CHECKSUM     -1
+#define IDDHTLIB_ERROR_TIMEOUT      -2
+#define IDDHTLIB_ERROR_ACQUIRING    -3
+#define IDDHTLIB_ERROR_DELTA        -4
+#define IDDHTLIB_ERROR_NOTSTARTED   -5
+
+#define IDDHTLIB_CHECK_STATE        if(state == STOPPED)            \
+                        return status;          \
+                    else if(state != ACQUIRED)      \
+                        return IDDHTLIB_ERROR_ACQUIRING;
+                                    
+class idDHTLib
+{
+public:
+    idDHTLib(PinName pin, void (*isrCallback_wrapper)());
+    void init(PinName pin, void (*isrCallback_wrapper)());
+    void dht11Callback();
+    void dht22Callback();
+    int acquire();
+    int acquireAndWait();
+    float getCelsius();
+    float getFahrenheit();
+    float getKelvin();
+    double getDewPoint();
+    double getDewPointSlow();
+    float getHumidity();
+    bool acquiring();
+    int getStatus();
+    
+private:
+    Timer t;
+    void (*isrCallback_wrapper)(void);
+    pFunctionPointer_t  handler;
+    enum states{RESPONSE=0,DATA=1,ACQUIRED=2,STOPPED=3,ACQUIRING=4};
+    volatile states state;
+    volatile int status;
+    volatile char bits[5];
+    volatile char cnt;
+    volatile char idx;
+//    volatile int us;
+    
+    DigitalInOut inOut;
+    InterruptIn intIn;
+    PinName pin;
+    volatile float hum;
+    volatile float temp;
+    void isrCallback(bool dht22);
+};
+#endif // idDHTLib_H__
\ No newline at end of file