DTH22, RHT03 and DTH11 sensors can be read with this code!

This DHT22 sensor reading class works with the mbed LPC1768. The code is time dependent but has been tested with mbed LPC1768 currently. I may add timing defines for other platforms if needed but i currently only use the mbed LPC1768 platform. Please feel free to import the code and modify it for other platforms if needed. BITREADTIME define and STARTTRANSBITSIZE define would be the main items to change for any other platform to operate properly. BITREADTIME is the us time value used in a basic look for a wait value to get next reading. This may work simply on other platforms at other system speeds but it may not. A more general solution maybe to add another calculation that generates these defines based on some platform speed value. At this writing the code performs very well with little to no read failures(in fact i have not seen a read failure yet in testing). The issues that i have seen with other classes and this sensor is the fact that the sensor always produces the correct Temperature and Humidity output values on the io pin but the class reading these values miss many reading causing errors. This class avoids this because it reads the output from the DTH22 sensor completely and then processes the values from a run length bit measurement perspective that i feel is far more accurate. Anyways the results speak for them self.

I have now added a member function for reading the DTH11 sensor as it is read the same way as the DTH22 sensor. The only difference is the final use of the retrieved bytes from the sensor for calculating the temperature and humidity. Note the DTH11 sensor has less range and less accuracy but it also can be found for less money!

Files at this revision

API Documentation at this revision

Comitter:
harrypowers
Date:
Tue Dec 03 09:09:07 2013 +0000
Parent:
1:d41fcc541836
Child:
3:57c9abcd9646
Commit message:
fully working class with test word available as public member.

Changed in this revision

DTH22.cpp Show annotated file Show diff for this revision Revisions of this file
DTH22.h Show annotated file Show diff for this revision Revisions of this file
--- a/DTH22.cpp	Mon Dec 02 08:48:29 2013 +0000
+++ b/DTH22.cpp	Tue Dec 03 09:09:07 2013 +0000
@@ -12,14 +12,79 @@
 
 int DTH22::getTH(int *temp,int *humidity)
 {
+    signed short int bytes[5];
+    int checksumtest = 0;
+    bool tempsign = false;
+    DTH22::getraw();
+    DTH22::getrawbits();
+    // check transmission type errors
+    if(transmissionErrors()!=0) return transmissionErrors();
+    // group bits into bytes
+    for(int j = 0; j < 5; j++) {
+        bytes[j] = 0;
+        for(int i = 0; i < 8; i++) {
+            if(rawdatabits[(i+(j*8))]==true) bytes[j]=bytes[j] | 1;
+            if(i!=7) bytes[j]=bytes[j] << 1;
+        }
+    }
+    // checksum error test
+    for(int i = 0; i < 4; i++){
+        checksumtest += bytes[i];
+    }
+    checksumtest = checksumtest & 255;  // only want the last byte for test
+    if(checksumtest!=bytes[4]) return CHECKSUMFAIL ;
+    // get rH
+    *humidity = (int)((bytes[0] << 8) | bytes[1]);
+    // get temp 
+    if((bytes[2]&128)!=0) tempsign = true;
+    bytes[2] = bytes[2] & 127;
+    *temp = (int)((bytes[2] << 8) | bytes[3]);
+    if(tempsign) *temp = *temp * -1;
     return 0;
 }
 
-void DTH22::getraw(int *data)
+int DTH22::testing(bool *bits,signed short int *data,int *temp,int *humidity)
+{
+    signed short int bytes[5];
+    int checksumtest = 0;
+    bool tempsign = false;
+    DTH22::getraw();
+    DTH22::getrawbits();
+    for(int i = 0; i < 40; i ++) {
+        bits[i]=rawdatabits[i];
+    }
+    if(transmissionErrors()!=0) return transmissionErrors();
+    // group bits into bytes
+    for(int j = 0; j < 5; j++) {
+        bytes[j] = 0;
+        for(int i = 0; i < 8; i++) {
+            if(rawdatabits[(i+(j*8))]==true) bytes[j]=bytes[j] | 1;
+            if(i!=7) bytes[j]=bytes[j] << 1;
+        }
+    }
+    // checksum test
+    for(int i = 0; i < 4; i++){
+        checksumtest += bytes[i];
+    }
+    checksumtest = checksumtest & 255;  // only want the last byte for test
+    if(checksumtest!=bytes[4]) return CHECKSUMFAIL ;
+    // get rH
+    *humidity = (int)((bytes[0] << 8) | bytes[1]);
+    // get temp 
+    if((bytes[2]&128)!=0) tempsign = true;
+    bytes[2] = bytes[2] & 127;
+    *temp = (int)((bytes[2] << 8) | bytes[3]);
+    if(tempsign) *temp = *temp * -1;
+    for(int i = 0; i < 5; i++) {
+        data[i]=bytes[i];
+    }
+    return 0;
+}
+void DTH22::getraw()
 {
     int counter = 0;
     for(int i = 0; i < 100; i++) {
-        data[i] = 0;
+        timingData[i] = 0;
     }
     DTH22pin.mode(OpenDrain);
     DTH22pin.output();
@@ -34,17 +99,17 @@
         if(junk==1) rawdata[i] = true;
         wait_us(BITREADTIME);
     }
-
     for (int j = 0; j < 100; j++) {
         if(counter < MAXRAWDATA) {
-            data[98] = counter ;
-            data[j] = transistionCount(counter);
-            if(data[j]>=MAXBITCOUNT) {
+            timingData[98] = counter ;
+            timingData[j] = transistionCount(counter);
+            if(timingData[j]>=MAXBITCOUNT) {
                 j = 101;
             } else {
-                counter = counter + data[j] ;
+                counter = counter + timingData[j] ;
             }
         } else {
+            //timingData[j] = counter;
             j = 101;
         }
     }
@@ -64,8 +129,29 @@
     return count;
 }
 
-int DTH22::currentpin()
+int DTH22::transmissionErrors()
 {
-    DTH22pin.input();
-    return DTH22pin;
-}
\ No newline at end of file
+    if(timingData[83]!=0) {
+        return DATANOISE ;
+    }
+    for(int i = 2; i < 81; i += 2) {
+        if(!((timingData[i]>=(STARTTRANSBITSIZE - 2))||(timingData[i]<=(STARTTRANSBITSIZE + 2)))) {
+            return STIMINGFAIL ;
+        }
+    }
+    if(timingData[98]>=(MAXRAWDATA - MAXBITCOUNT)) {
+        return DATANOISE2 ;
+    }
+    return 0;
+}
+
+void DTH22::getrawbits()
+{
+    int counter = 0;
+    bool bitvalue = false;
+    for(int i=2; i < 81; i += 2) {
+        if(timingData[i+1]>=timingData[i]) bitvalue = true;
+        rawdatabits[counter++] = bitvalue;
+        bitvalue = false;
+    }
+}
--- a/DTH22.h	Mon Dec 02 08:48:29 2013 +0000
+++ b/DTH22.h	Tue Dec 03 09:09:07 2013 +0000
@@ -58,8 +58,14 @@
  */
 
 #define MAXRAWDATA 1300
+#define DATABITS 40
 #define BITREADTIME 3
 #define MAXBITCOUNT 30
+#define STARTTRANSBITSIZE 14
+#define DATANOISE 2000
+#define STIMINGFAIL 2001
+#define DATANOISE2 2002
+#define CHECKSUMFAIL 2003
 
 class DTH22
 {
@@ -85,14 +91,19 @@
     * @param returns 0 for no errors.  Any other number is some type of communication error and data might not be valid!
     */
     int getTH(int *temp,int *humidity);    // get both temperature and pressure fully compensated values! Note this only returns when measurements are complete
-    void getraw(int *data);
-    int currentpin();
+    int testing(bool *bits,signed short int *data,int *temp,int *humidity);
     
 protected:
     DigitalInOut DTH22pin;
     bool rawdata[MAXRAWDATA];
+    unsigned short int timingData[100];
+    //int temperature, humidity, checksum;
+    bool rawdatabits[DATABITS];
     
+    void getraw();
+    void getrawbits();
     int transistionCount(int index);
+    int transmissionErrors();
 };
 
 #endif
\ No newline at end of file