Go Down

Topic: Class for DHT11, DHT21 and DHT22 (temperature & humidity) (Read 109182 times) previous topic - next topic

robtillaart

Hi Monotok,

I have very little time to investigate but the question is interesting as I never tested the lib in combination with VW.

The version 0.1.03 is rather old, can you please confirm the bug exists with the 0.1.13 version a.k.a. DHTstable?

https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTstable

Thanks,
Rob
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

monotok

Hello Rob,

Thank you very much for your quick reply and that's Ok, I'll be fiddling with it so will let you know if I find anything.

My apologies, I was using version 0.1.21 from GitHub before. Here are the results:
Code: [Select]

dht22_test.ino
LIBRARY VERSION: 0.1.21

Type, status, Humidity (%), Temperature (C) Time (us)
DHT22, Checksum error, 90.6, 39.7, 6760
DHT22, Checksum error, 74.1, 79.6, 6648
DHT22, Checksum error, 90.0, 43.4, 6640
DHT22, Checksum error, 64.3, 19.6, 6176
DHT22, Checksum error, 70.6, 19.6, 6120



The stable version produces timeout errors instead.

Code: [Select]
dht22_test.ino
LIBRARY VERSION: 0.1.13

Type, status, Humidity (%), Temperature (C) Time (us)
DHT22, Time out error, -999.0, -999.0, 9000
DHT22, Time out error, -999.0, -999.0, 8888
DHT22, Time out error, -999.0, -999.0, 8944
DHT22, Time out error, -999.0, -999.0, 8952
DHT22, Time out error, -999.0, -999.0, 9000
DHT22, Time out error, -999.0, -999.0, 8952
DHT22, Time out error, -999.0, -999.0, 8992
DHT22, Time out error, -999.0, -999.0, 8912


I tried Virtual Wire's replacement (RadioHead) and that does the same thing. Quite an interesting "bug"  and surprised no body has encountered this before with quite a few people making weather stations.

Thanks  :)

robtillaart

Can you tell which boards you are using?
Do you use a pull up resistor on the data line of the DHT sensor?
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

monotok

Hello,

Some good news! First I will answer your question. I am using a Uno R3 as a programmer to a Atmega 328P chip on a breadboard using it's own internal 8Mhz clock. I haven't used a resistor because I don't think I need one because I am using this http://www.banggood.com/AM2302-DHT22-Temperature-And-Humidity-Sensor-Module-For-Arduino-SCM-p-937403.html which I think has it's own inbuilt resistor.

So the good news is I seem to have modified your library (Very quickly and dodgy) and it now seems to work.

Code: [Select]
DHT22, OK, 70.4, 19.8, 3960
DHT22, OK, 70.4, 19.8, 3960
DHT22, OK, 70.4, 19.8, 4016
DHT22, OK, 70.4, 19.8, 4008

TOT OK CRC TO UNK
180 180 0 0 0 0 0 0


So I looked at your code, Adafruits library and the datasheet. The adafruit library mentioned part of the process of getting the bits back from the chip is timing critical and used an interrupt class to temporarily stop interrupts. I took the class and added it to your header file and then placed the same class call into your cpp file.

I am very very surprised but it seems to have fixed it somehow, maybe the Virtual library is causing the Atmega to be interrupted every time it hears a RF signal on 433Mhz?

Here is the class in the header.

Code: [Select]
class InterruptLock {
  public:
   InterruptLock() {
    noInterrupts();
   }
   ~InterruptLock() {
    interrupts();
   }

};
#endif
//
// END OF FILE
//


Here is the call in the CPP file.
Code: [Select]

// REQUEST SAMPLE
    pinMode(pin, OUTPUT);
    digitalWrite(pin, LOW); // T-be
    delayMicroseconds(wakeupDelay * 1000UL);
    InterruptLock lock;
    digitalWrite(pin, HIGH); // T-go
    pinMode(pin, INPUT);


Anyway; do you think this is a good idea and should be added? Your library now works with my sensor code.

Hope this is helpful.

EDIT:
LED Receive light works, forgot to un-comment the code to make it go off.

monotok

Just to add to my previous comment. I have left it running in my sensor code using VirtualWire and I have got 18,000 "Ok's" and Zero errors. 100% success rate is great, so disabling the interrupts in that function might have increased the success rate even further as I got 0.06% (9 out of 14,000) before.

Thanks

Clemens

DHT lib outputs humidity and temperature values from the point in time of the reading before

I did some tests with a longer delay (20 min) between the DHT sensor readings, I noticed a significant offset between the DHT values and some DS18B20 temp sensors readings in parallel. After a rain shower I noticed also some implausible data values: It starts to rain but the next reading about 10 minutes after did report very "dry" values and only the next reading reports correct "wet" values.

So I did some tests with the sketch below. It reads values every 10 seconds but also a "control reading" 500 ms after the first reading. To trigger sensor changes I breathe upon the sensor to increase humidity, this is directly after last reading, around 9 seconds before next reading. So the sensor has enough time to "warm up" / catch the change. 

I got the same results as in my 20 minutes setting (detailed output see below after the code): The reading is NOT the value for the current time but represents the situation of the last measurement. It seams with "DHT.readxx" is done a reading but this reading will be outputted not in the following Serial.print(DHT.temperature, 1); but in outputs just after that, so "one data point too late".

Is this the way the DHT works??--I did not see any comment about that?? Or is there an error in the lib or in my code (a modification of the lib example)?

Code: [Select]
#include <dht.h>
dht DHT;
#define DHT33_PIN 7

struct{
    uint32_t total;
    uint32_t ok;
    uint32_t crc_error;
    uint32_t time_out;
    uint32_t connect;
    uint32_t ack_l;
    uint32_t ack_h;
    uint32_t unknown;
} stat = { 0,0,0,0,0,0,0,0};

void setup(){
    Serial.begin(9600);
    Serial.print("LIBRARY VERSION: ");
    Serial.println(DHT_LIB_VERSION);
    Serial.println();
    Serial.println("Type,\tstatus,\tHumidity (%),\tTemperature (C)\tTime (us)");
}

void loop(){
    readData();
    Serial.print("\t");
    Serial.print("delay 500");
    Serial.println();
    delay(500);
   
    readData();
    Serial.print("\t");
    Serial.print("delay 10000");
    Serial.println();
    delay(10000);
    Serial.println();
}

void readData(){
    // READ DATA
    Serial.print("DHT33, \t");

    uint32_t start = micros();
    int chk = DHT.read33(DHT33_PIN);
    uint32_t stop = micros();

    stat.total++;
    switch (chk)
    {
    case DHTLIB_OK:
        stat.ok++;
        Serial.print("OK,\t");
        break;
    case DHTLIB_ERROR_CHECKSUM:
        stat.crc_error++;
        Serial.print("Checksum error,\t");
        break;
    case DHTLIB_ERROR_TIMEOUT:
        stat.time_out++;
        Serial.print("Time out error,\t");
        break;
    default:
        stat.unknown++;
        Serial.print("Unknown error,\t");
        break;
    }
    // DISPLAY DATA
    Serial.print(DHT.humidity, 1);
    Serial.print(",\t");
    Serial.print(DHT.temperature, 1);
    Serial.print(",\t");
    Serial.print(stop - start);

    if (stat.total % 20 == 0)    {
        Serial.println("\nTOT\tOK\tCRC\tTO\tUNK");
        Serial.print(stat.total);
        Serial.print("\t");
        Serial.print(stat.ok);
        Serial.print("\t");
        Serial.print(stat.crc_error);
        Serial.print("\t");
        Serial.print(stat.time_out);
        Serial.print("\t");
        Serial.print(stat.connect);
        Serial.print("\t");
        Serial.print(stat.ack_l);
        Serial.print("\t");
        Serial.print(stat.ack_h);
        Serial.print("\t");
        Serial.print(stat.unknown);
        Serial.println("\n");
    }
}


What I get is this
Code: [Select]
LIBRARY VERSION: 0.1.13

Type, status, Humidity (%), Temperature (C) Time (us)
DHT33, OK, 28.4, 23.5, 5096 delay 500
DHT33, OK, 28.3, 23.5, 5240 delay 10000

DHT33, OK, 28.3, 23.5, 5232 delay 500
DHT33, Time out error, -999.0, -999.0, 6936 delay 10000

DHT33, OK, 28.3, 23.5, 5240 delay 500
DHT33, OK, 29.4, 23.5, 5160 delay 10000

=> directly after last reading breathing upon the sensor to 
=> increse humidity, this is around 9 seconds before next reading

DHT33, OK, 29.4, 23.5, 5152 delay 500    ??? why is this value (29.4) so low ???
DHT33, OK, 74.4, 23.5, 5336 delay 10000  !!! 74.4 is now ok and "wet", but environment did not change in 500 ms !!!   

DHT33, OK, 74.6, 23.5, 5416 delay 500
DHT33, OK, 69.4, 24.3, 5392 delay 10000

DHT33, OK, 68.8, 24.3, 5240 delay 500
DHT33, OK, 55.8, 24.2, 5152 delay 10000

DHT33, OK, 55.2, 24.2, 5112 delay 500
DHT33, OK, 42.0, 23.8, 5232 delay 10000

DHT33, OK, 41.6, 23.8, 5240 delay 500
DHT33, OK, 36.0, 23.8, 5288 delay 10000

=> again: directly after last reading breathing upon the sensor to 
=> increse humidity, this is around 9 seconds before next reading

DHT33, OK, 35.9, 23.8, 5336 delay 500    ??? same behavior, why is this value (35.9) so low ???
DHT33, OK, 87.1, 23.9, 5432 delay 10000 !!! 87.1 is now ok and "wet", but environment did not change in the last 500 ms !!!   

DHT33, OK, 87.9, 23.9, 5424 delay 500
DHT33, OK, 86.1, 24.2, 5288
TOT OK CRC TO UNK
20 19 0 1 0 0 0 0

 delay 10000

DHT33, OK, 84.6, 24.2, 5248 delay 500
DHT33, OK, 48.6, 24.1, 5288 delay 10000

DHT33, OK, 47.5, 24.1, 5384 delay 500
DHT33, OK, 35.9, 24.1, 5296 delay 10000

Clemens

The offset problem in my last post was tested with two different DHT33 sensors. To be sure not the sensors types are the problem I tested with DHT22 sensors also: Same result, always this one reading point offset!

The only software fix that is working is reading the sensor twice with a 500 ms delay between:

Code: [Select]

    DHT.read22(DHT22_PIN);
    delay(500);
    int chk = DHT.read22(DHT22_PIN);


But this is not the way I want to go. My nodes are optimized for battery powering and so this is not really a good solution.

I tested it also with the Adafruit DHT lib and the results gone more worse: The update of a "reality" value happened two or three datapoints after the breathing event.

I have the 4k7 resistor (between data and Vcc) on the shield, then a 50 cm cable connects the sensor with the shield, but I have also tested with 10 cm cable also with no better results. Could this have any influence of the offset / delay or additional capacitors I saw on some breakouts? I think not - because I got a reading, but perhaps someone out has better ideas?

I still do not know: it's a hardware problem / knowing issue for the DHT or a software problem on the library?

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy