Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 24 of 24

Thread: DHT22 checksum error for negative temperatures

  1. #1
    Senior Member
    Join Date
    Apr 2018
    Location
    Eastern Time, USA
    Posts
    181

    DHT22 checksum error for negative temperatures

    Hi,

    I am using the DHTlib with a DHT22 and a Teensy 3.2. The code works okay for temperatures greater than 0C. However, when the temperature drops below 0C, it returns a checksum error. The datasheet for the sensor says it works over the range -40C to 80C.

    So, is this a library problem, perhaps already known, or is something wrong with the sensor?

    Code follows.

    Thank you


    Code:
    #include <dht.h> 
    
    dht DHT;
    #define DHT22_PIN 7
    #define DHTPWR 8
    
     pinMode(DHTPWR,OUTPUT);
     digitalWrite(DHTPWR,HIGH);  // +Vcc to DHT
    
    
         int chk = DHT.read22(DHT22_PIN);
    
          switch (chk)
    	{
    	case DHTLIB_OK:  
    	  // DISPLAY DATA
    	  h = DHT.humidity;
    	  t = DHT.temperature;
    	  sendprintf( (char *)"Temperature %.1f Humidity %.1f ", t, h );
    	  break;
    	case DHTLIB_ERROR_CHECKSUM: 
    	  sendstring( (char *)"Error: DHT Checksum"); 
    	  break;
    	case DHTLIB_ERROR_TIMEOUT: 
    	  sendstring( (char *)"Error: DHT Time out"); 
    	  break;
    	case DHTLIB_ERROR_CONNECT:
    	  sendstring( (char *)"Error: DHT Connect");
    	  break;
    	case DHTLIB_ERROR_ACK_L:
    	  sendstring( (char *)"Error: DHT Ack Low");
    	  break;
    	case DHTLIB_ERROR_ACK_H:
    	  sendstring( (char *)"Error: DHT Ack High");
    	  break;
    	default: 
    	  sendstring( (char *)"Error: DHT Unknown"); 
    	  break;
    	}
          
          sendstring( (char *)"done" );

    For negative temperatures the

  2. #2
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,864
    Which library are you using? The one I have (by Adafruit) does not have a read22() method.

    Pete

  3. #3
    Senior Member
    Join Date
    Apr 2018
    Location
    Eastern Time, USA
    Posts
    181
    I cited it, it is called DHTlib, and it is written by Rob Tillaart

  4. #4
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,864
    Can you try the Adafruit library - it's in the Library Manager?

    Pete

  5. #5
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,707
    this DHT lib https://www.arduino.cc/reference/en/libraries/dhtlib/ says it is designed for AVR processors -- Teensy 3.2 is ARM not AVR. lib is using AVR registers for IO
    Code:
        // replace digitalRead() with Direct Port Reads.
        // reduces footprint ~100 bytes => portability issue?
        // direct port read is about 3x faster
        uint8_t bit = digitalPinToBitMask(pin);
        uint8_t port = digitalPinToPort(pin);
        volatile uint8_t *PIR = portInputRegister(port);
    as Pete suggests, try the adafruit DHT-sensor-library

  6. #6
    Senior Member
    Join Date
    Apr 2018
    Location
    Eastern Time, USA
    Posts
    181
    If I thought it was a hardware problem, then trying another library might be a good way to check. But, I have two of these sensors, so maybe I'll just try the other one first.

    I suspect it is not hardware. Hence the question, is this a known bug in the library? Maybe the author can answer.

  7. #7
    Senior Member
    Join Date
    Apr 2018
    Location
    Eastern Time, USA
    Posts
    181
    @manitou and @el_supremoe Thank you, that makes sense now, I'll try it. It raises another question, why the incompatibility isnt flagged in the development environment.

  8. #8
    Senior Member
    Join Date
    Apr 2018
    Location
    Eastern Time, USA
    Posts
    181
    @manitou and @el_supremo So, still not working.

    The Adafruit DHT-sensor-library reports a temperature of -3272.4C.

    An impressive and stunning repudiation of the third law of thermodynamics.

    (Temperatures above 0C seem to be correct to reasonable accuracy).


    Here are the relevant lines from the code:

    Code:
    #include "DHT.h
    
    // DHT sensor
    #define DHTPIN 7
    #define DHTPWR 8
    #define DHTTYPE DHT22
    
    DHT dht(DHTPIN, DHTTYPE);
    
    /* I/O support
    */
    int sendbuffer( void *p, size_t nlen ) {
      size_t written = 0;
      while( written != nlen ) {
        written += Serial.write( (char *)p+written, nlen-written);
      }
      return written;
    }
    
    int sendprintf( char *fmt, ... ) {
      va_list ap;
      char sbuf[128];
      int nlen;
      va_start(ap, fmt);
      nlen = vsnprintf(sbuf, sizeof(sbuf), fmt, ap);
      va_end(ap);
      sendbuffer(sbuf,nlen+1);
      return nlen;
    }
    
    
    void setup() {
    
      // ...
    
      pinMode(DHTPWR,OUTPUT);
      digitalWrite(DHTPWR,HIGH);  // +Vcc for DHT
    
      dht.begin();
    
      // ...
    }
    
    void loop() {
    
        // other stuff
    
       if ( commandmatch( command, 'temperature' ) ) {
    
          float h, t;
    
          h = dht.readHumidity();
          t = dht.readTemperature();
          
          if ( isnan(h) || isnan(t) ) {
    	sendstring( (char *)"Error: Failed to read from DHT sensor");
          }
          else {
    	sendprintf( (char *)"Temperature %.1f Humidity %.1f ", t, h );
          }
          
          sendstring( (char *)"done" );      
    
       }
    
    
      // more other stuff
    }
    Last edited by DrM; 05-29-2022 at 09:08 PM.

  9. #9
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,864
    Try this:
    Code:
    DHT dht(DHTPIN, DHTTYPE, 27);
    and see my old thread about problems with the DHT22 on Teensy 3.

    If that doesn't help, let's try adding a debugging print in the library. Near the end of the read() function in DHT.cpp is this comment:
    Code:
      // check we read 40 bits and that the checksum matches
    Put this print statement immediately before the comment:
    Code:
      Serial.printf("DEBUG: %02X %02X %02X %02X : %02X\n",
    				data[0],data[1],data[2],data[3] ,data[4]);
    Pete

  10. #10
    Senior Member
    Join Date
    Apr 2018
    Location
    Eastern Time, USA
    Posts
    181
    @el_supremo no luck, still shows -3272C.

    DEBUG: 02 43 FF CF : 13
    Last edited by DrM; 05-29-2022 at 09:43 PM.

  11. #11
    Senior Member
    Join Date
    Apr 2018
    Location
    Eastern Time, USA
    Posts
    181
    temperature is -3272

    DEBUG: 02 43 FF CF : 13

  12. #12
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,864
    What is the actual temperature?

    I'm suspicious that the device actually represents the temperature as twos-complement, whereas both libraries treat it as sign-magnitude.
    If it is twos-complement, FFCF would represent a temperature of -4.9C (23.2F).
    If that is correct, I'll work out a fix for the library.

    Pete

  13. #13
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,864
    Replace the debug printf with this which will add my interpretation of the temperature (I hope - untested):
    Code:
      Serial.printf("DEBUG: %02X %02X %02X %02X : %02X (%6.2f)\n",
    				data[0],data[1],data[2],data[3] ,data[4],
    				((int16_t)((data[2]<<8) | data[3]))/10.;
    Pete

  14. #14
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    10,535
    Two thread on this?
    As I mentioned in the other one there are several open issues on the Adafruit library about this as well as a Pull Request

  15. #15
    Senior Member
    Join Date
    Apr 2018
    Location
    Eastern Time, USA
    Posts
    181
    @el_supremo I have to get the experiment started now, its getting late and i need it to finish by a certain time. But, fortunately, I do have another cold stage with another DHT22, so i'll get that started and continue working on this after the launch.

  16. #16
    Senior Member
    Join Date
    Apr 2018
    Location
    Eastern Time, USA
    Posts
    181
    DEBUG: 03 E7 00 50 : 3A ( 8.00)
    Temperature 8.0 Humidity 99.9


    Unfortunately that cold stage is not going below 0C

  17. #17
    Senior Member
    Join Date
    Apr 2018
    Location
    Eastern Time, USA
    Posts
    181
    @el_supremo, That is actually correct!!! (twos complement vs sign magnitude)

    -4.9C is what I read previously with a thermistor and DVM.

    I apologize (and regret) that I didnt parse the fine print sooner. I was in a hurry to get the run started (it's running with a thermistor).

    Thank you for working on this, please do let me know when it is fixed.

  18. #18
    Senior Member
    Join Date
    Apr 2018
    Location
    Eastern Time, USA
    Posts
    181
    @el_supremo

    Here is a revision for your DHT.cpp to fix the problem for the DHT22. I tested it just now, it seems to work.

    Aside, I read the data sheet, it does seem confusing on this point.


    Code:
    float DHT::readTemperature(bool S, bool force) {
      float f = NAN;
    
      int16_t i16temp;
      
      if (read(force)) {
        switch (_type) {
        case DHT11:
          f = data[2];
          if (data[3] & 0x80) {
            f = -1 - f;
          }
          f += (data[3] & 0x0f) * 0.1;
          if (S) {
            f = convertCtoF(f);
          }
          break;
        case DHT12:
          f = data[2];
          f += (data[3] & 0x0f) * 0.1;
          if (data[2] & 0x80) {
            f *= -1;
          }
          if (S) {
            f = convertCtoF(f);
          }
          break;
        case DHT22:
        case DHT21:
          i16temp = data[3] | (data[2] <<8) ;
          f = i16temp/10.;
    
          /*
          f = ((word)(data[2] & 0x7F)) << 8 | data[3];
          f *= 0.1;
          if (data[2] & 0x80) {
            f *= -1;
          }
          */
          if (S) {
            f = convertCtoF(f);
          }
          break;
        }
      }
      return f;
    }

  19. #19
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,864
    That should do it.

    Pete

  20. #20
    Senior Member
    Join Date
    Apr 2018
    Location
    Eastern Time, USA
    Posts
    181
    Yep. and it turns out to be very useful. How do we (or do we), get this into the code for the library? Also, I notice there are a few other cases where it assumes sign-magnitude. I can fix the other cold stage and check the DHT11 that I have here, but support for the other devices would seem to remain open. Perhaps a good solution would be to provide a switch in the API for 2s-complement vs sign-magnitude.

  21. #21
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,864
    I see one potential problem with your fix. The DHT21 might use sign-magnitude in which case you would need to split the DHT21 and DHT22 cases so that they handle the negative numbers correctly for that device.

    Pete

  22. #22
    Senior Member
    Join Date
    Apr 2018
    Location
    Eastern Time, USA
    Posts
    181
    Of course, and perhaps that goes for any of them. Hence it seems like a good idea to add a parameter (perhaps in the class intializer) to select it manually.
    Last edited by DrM; 05-31-2022 at 01:35 AM.

  23. #23
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,864
    I don't think that would be useful. Having an option of using sign-magnitude for the DHT22 is pointless and potentially confusing because it only uses twos-complement. Similarly, there's not much point having an option to read a DHT11 as twos-complement when it (apparently) uses sign-magnitude.

    Pete

  24. #24
    Senior Member
    Join Date
    Apr 2018
    Location
    Eastern Time, USA
    Posts
    181
    Well, it depends. Are the DHT22 reliably all twos-complement? And converse for the DHT11? Etc. And, besides number of bytes and sign versus 2's, are the devices different in any other way?

    It seems like the error in the DHT22 perhaps was not picked up because it wasn't tested. So, we might not know what is going on with the others.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •