DHT22 problem

Posted on
  • Running a PICO V1.87
    This code

    //DHT22.js
    //10Oct2016
    
    var dpin=B3;
    var F;
    var H;
    
    var dht = require("DHT22").connect(dpin);
    
    setInterval(function () {
    //  dht.read(function (a) {});
      dht.read(function (a) {
     F=(a.temp+40)*9/5-40;
     H=a.rh;
      console.log("Temp is "+F.toString()+" and RH is "+H.toString());
    });
    }, 1000);
    

    produces the following output

    >echo(0);
    =undefined
    Temp is 30.2 and RH is -1
    Temp is 30.2 and RH is -1
    Temp is 30.2 and RH is -1
    Temp is 30.2 and RH is -1
    Temp is 71.6 and RH is 52
    Temp is 30.2 and RH is -1
    Temp is 30.2 and RH is -1
    Temp is 30.2 and RH is -1
    Temp is 71.6 and RH is 51.6
    Temp is 30.2 and RH is -1
    Temp is 71.78 and RH is 51.6
    Temp is 30.2 and RH is -1
    Temp is 71.78 and RH is 51.6
    >clearInterval();
    =undefined
    

    But this code

    //DHT22.js
    //10Oct2016
    
    var dpin=B3;
    var F;
    var H;
    
    var dht = require("DHT22").connect(dpin);
    
    setInterval(function () {
      dht.read(function (a) {});
      dht.read(function (a) {
     F=(a.temp+40)*9/5-40;
     H=a.rh;
      console.log("Temp is "+F.toString()+" and RH is "+H.toString());
    });
    }, 1000);
    

    Produces this output

    >echo(0);
    =undefined
    Temp is 71.78 and RH is 51.6
    Temp is 71.96 and RH is 51.7
    Temp is 71.78 and RH is 51.6
    Temp is 71.78 and RH is 51.6
    Temp is 71.78 and RH is 51.6
    Temp is 71.78 and RH is 51.6
    Temp is 71.78 and RH is 51.6
    Temp is 71.6 and RH is 51.5
    Temp is 71.78 and RH is 51.6
    Temp is 71.78 and RH is 51.8
    Temp is 71.78 and RH is 51.8
    >clearInterval();
    =undefined
    > 
    

    Is there something missing in the module code?
    Pin initialization?
    A bit?

  • You know about it returning -1 if there are problems reading the data? That will happen occasionally so you need to be sure to ignore them.

    Running two reads at the same time is a really bad idea as multiple watches/timeouts get queued up - see the actual code: https://github.com/espruino/EspruinoDocs­/blob/master/devices/DHT22.js

    Are you sure you've got it wired up right? I suppose you might expect this if the 3.3v line wasn't connected properly?

    I guess you could try copy/pasting the code from the module and fiddling with the value used for setTimeout? I'm struggling to see how there could be much other difference

  • The only real downside of this sensor is you can only get new data from it once every 2 seconds.
    From
    https://www.adafruit.com/product/385

  • Ahh - so polling every second might well have confused it?

  • Let me restate the problem.
    I pulled the DHT22.js module and inserted a console.log for illustration.
    Here is where the console.log was inserted

        delete ht.watch;
        var cks = 
    
            parseInt(d.substr(2,8),2)+
            parseInt(d.substr(10,8),2)+
            parseInt(d.substr(18,8),2)+
            parseInt(d.substr(26,8),2);
        console.log('n=',n,'len=',d.length,' cks=',cks&0xFF,' chsum=',parseInt(d.substr(34,8),2));
        if (cks&&((cks&0xFF)==parseInt(d.substr(34,­8),2))) {
    
    

    The example code

    var dht=new DHT22(dpin);
    
    setInterval(function () {
      dht.read(function (a) {
     F=a.temp;
     H=a.rh;
      console.log("Temp is "+F.toString()+" and RH is "+H.toString());
    });
    }, 2000);
    

    Produces the following output:

    n= 3 len= 42  cks= 201  chsum= 201
    Temp is 23.2 and RH is 48
    n= 10 len= 0  cks= 0  chsum= NaN
    n= 6 len= 0  cks= 0  chsum= NaN
    n= 9 len= 42  cks= 201  chsum= 201
    Temp is 23.2 and RH is 48
    n= 5 len= 0  cks= 0  chsum= NaN
    n= 4 len= 42  cks= 202  chsum= 202
    Temp is 23.2 and RH is 48.1
    n= 10 len= 42  cks= 202  chsum= 202
    Temp is 23.2 and RH is 48.1
    n= 10 len= 42  cks= 202  chsum= 202
    Temp is 23.2 and RH is 48.1
    n= 10 len= 42  cks= 201  chsum= 201
    Temp is 23.2 and RH is 48
    n= 10 len= 42  cks= 201  chsum= 201
    Temp is 23.2 and RH is 48
    n= 10 len= 40  cks= 200  chsum= 50
    n= 9 len= 41  cks= 200  chsum= 100
    n= 8 len= 41  cks= 200  chsum= 100
    n= 7 len= 42  cks= 201  chsum= 201
    Temp is 23.2 and RH is 48
    n= 10 len= 0  cks= 0  chsum= NaN
    n= 9 len= 42  cks= 201  chsum= 201
    Temp is 23.2 and RH is 48
    n= 10 len= 42  cks= 202  chsum= 202
    Temp is 23.2 and RH is 48.1
    n= 10 len= 42  cks= 201  chsum= 201
    Temp is 23.2 and RH is 48
    

    Notice that the module code produces a lot of retries n. 1st try n=10, 2nd try n=9...

    By changing the example code to

    var dht=new DHT22(dpin);
    setInterval(function () {
      dht.read(function (a) {});
      dht.read(function (a) {
     F=a.temp;
     H=a.rh;
      console.log("Temp is "+F.toString()+" and RH is "+H.toString());
    });
    }, 2000);
    

    Which gives to following output

    >echo(0);
    =undefined
    n= 10 len= 43  cks= 201  chsum= 201
    n= 10 len= 43  cks= 201  chsum= 201
    Temp is 23.2 and RH is 48
    n= 10 len= 43  cks= 199  chsum= 199
    n= 10 len= 43  cks= 199  chsum= 199
    Temp is 23.2 and RH is 47.8
    n= 10 len= 43  cks= 198  chsum= 198
    n= 10 len= 43  cks= 198  chsum= 198
    Temp is 23.2 and RH is 47.7
    n= 10 len= 43  cks= 198  chsum= 198
    n= 10 len= 43  cks= 198  chsum= 198
    Temp is 23.2 and RH is 47.7
    n= 10 len= 43  cks= 198  chsum= 198
    n= 10 len= 43  cks= 198  chsum= 198
    Temp is 23.2 and RH is 47.7
    n= 10 len= 43  cks= 199  chsum= 199
    n= 10 len= 43  cks= 199  chsum= 199
    Temp is 23.2 and RH is 47.8
    n= 10 len= 43  cks= 199  chsum= 199
    n= 10 len= 43  cks= 199  chsum= 199
    Temp is 23.2 and RH is 47.8
    n= 10 len= 43  cks= 199  chsum= 199
    n= 10 len= 43  cks= 199  chsum= 199
    Temp is 23.2 and RH is 47.8
    

    This gives correct temperature and humidity readings without all the retries in the module code. From a programming perspective it is troubling as Gordon outlined above.
    Even with the setInterval =1000.

    And finally changing the example code one more time so that the one dht.read completes before the 2nd one starts.

    //var dht = require("DHT22").connect(dpin);
    var dht=new DHT22(dpin);
    setInterval(function () {
      dht.read(function (a) {//});
      dht.read(function (a) {
     F=a.temp;
    // F=(a.temp+40)*9/5-40;
     H=a.rh;
      console.log("Temp is "+F.toString()+" and RH is "+H.toString());
    });
        });
    }, 2000);
    
    

    This gives;

    =undefined
    n= 10 len= 40  cks= 199  chsum= 49
    n= 9 len= 42  cks= 197  chsum= 197
    n= 10 len= 0  cks= 0  chsum= NaN
    n= 9 len= 41  cks= 198  chsum= 99
    n= 8 len= 42  cks= 197  chsum= 197
    Temp is 23.2 and RH is 47.6
    n= 10 len= 0  cks= 0  chsum= NaN
    n= 9 len= 41  cks= 198  chsum= 99
    n= 8 len= 41  cks= 198  chsum= 99
    n= 7 len= 41  cks= 198  chsum= 99
    n= 10 len= 0  cks= 0  chsum= NaN
    n= 6 len= 41  cks= 198  chsum= 99
    n= 9 len= 0  cks= 0  chsum= NaN
    n= 5 len= 41  cks= 198  chsum= 99
    n= 8 len= 0  cks= 0  chsum= NaN
    n= 4 len= 42  cks= 197  chsum= 197
    n= 10 len= 0  cks= 0  chsum= NaN
    n= 7 len= 0  cks= 0  chsum= NaN
    n= 9 len= 42  cks= 197  chsum= 197
    Temp is 23.2 and RH is 47.6
    n= 10 len= 0  cks= 0  chsum= NaN
    n= 6 len= 0  cks= 0  chsum= NaN
    n= 9 len= 42  cks= 197  chsum= 197
    n= 10 len= 0  cks= 0  chsum= NaN
    n= 5 len= 0  cks= 0  chsum= NaN
    n= 4 len= 1  cks= 0  chsum= NaN
    n= 9 len= 43  cks= 197  chsum= 197
    Temp is 23.2 and RH is 47.6
    

    Changing the set interval from 1000 to 2000 helps.
    On a scope the entire message takes just under 6ms.

  • Changing the set interval from 1000 to 2000 helps.

    Is it substantially better? What about going slower still like 3000ms? As @Frida says, if the sensor can only provide a signal every 2 sec then I don't see what we can do if you request something every second?

    Possibly the module could be updated to warn the user if they call it too often?

    My guess is that sending the pulse twice as you were doing might reset the sensor somehow - but that's probably not going to give you very good readings.

  • If you need a higher data rate then a different sensor could be an alternative.
    The DHT22 is not state-of-the-art anymore (proprietary protocol, power consumption, low temperature accuracy, no heating support to prevent condensation). It was one of the first affordable humidity sensors but today there are many better alternatives with Espruino support (SHT2x, SHT3x, HTU21D, BME280, ..).

    One of the cheapest is the HTU21D/SHT21: http://www.ebay.com/itm/112049178633

  • Data rate is not an issue as I use the DH22 to turn my window AC on and off based on keeping temperature and RH within a comfort zone. In my climate humidity is a factor in maintaining comfort and temperature alone either freezes me or I wake up in the night with too much humidity. Sampling every minute or longer should suffice.

    As to the two second interval, the module code does up to 10 retires one after the other. Perhaps the 2 second specification is related to the accuracy of the reading and not to the ability to read data from the device.

    The hardware is setup on a solder less breadboard with 6 inch jumper wires and a 4.7k pullup resistors.

    As to the double pulse idea, I tried that and it doesn't trigger the device any better than the single pulse.

    Thanks for the alternate parts list, I will investigate.

  • Found a solution changed 6 to 60 on the outer setInterval of the module

    var dpin=B3;
    var F;
    var H;
    
    function DHT22(pin) {
      this.pin = pin;
    }
    
    DHT22.prototype.read = function (cb, n) {
      if (!n) n=10;
      var d = ""; 
      var ht = this;
      pinMode(ht.pin); // set pin state to automatic
      digitalWrite(ht.pin,0);
    //  digitalWrite([ht.pin,ht.pin,ht.pin,ht.pi­n,ht.pin],0x0a);
      this.watch = setWatch(function(t) {
        d+=0|(t.time-t.lastTime>0.00005);
      }, ht.pin, {edge:'falling',repeat:true} );
      setTimeout(function() {pinMode(ht.pin,'input_pullup');},1);
      setTimeout(function() {
        clearWatch(ht.watch);
        delete ht.watch;
        var cks = 
    
            parseInt(d.substr(2,8),2)+
            parseInt(d.substr(10,8),2)+
            parseInt(d.substr(18,8),2)+
            parseInt(d.substr(26,8),2);
        console.log(n,d.length,cks&0xFF,parseInt­(d.substr(34,8),2));
        if (cks&&((cks&0xFF)==parseInt(d.substr(34,­8),2))) {
          cb({ 
            raw : d,
            rh : parseInt(d.substr(2,16),2)*0.1,
            temp : parseInt(d.substr(19,15),2)*0.2*(0.5-d[1­8])
          });
        } else {
          if (n>1) setTimeout(function() {ht.read(cb,--n);},500);
          else cb({err:true, checksumError:cks>0, raw:d, temp:-1, rh:-1});
        }
      },60); //////Changed value to 60 from 6
    };
    
    //var dht = require("DHT22").connect(dpin);
    var dht=new DHT22(dpin);
    setInterval(function () {
      dht.read(function (a) {
     F=(a.temp+40)*9/5-40;
     H=a.rh;
      console.log("Temp is "+F.toString()+" and RH is "+H.toString());
    });
    //    });
    }, 1000);
    
    

    Sample output Temperature in F.

    >echo(0);
    =undefined
    10 42 164 164
    Temp is 71.96 and RH is 45.3
    10 42 164 164
    Temp is 71.96 and RH is 45.3
    10 42 164 164
    Temp is 71.96 and RH is 45.3
    10 42 164 164
    Temp is 71.96 and RH is 45.3
    10 42 164 164
    Temp is 71.96 and RH is 45.3
    10 42 164 164
    Temp is 71.96 and RH is 45.3
    10 42 164 164
    Temp is 71.96 and RH is 45.3
    10 42 164 164
    Temp is 71.96 and RH is 45.3
    
  • How many retries does it use then?

    That looks like a good fix - I can't see it causing any problems.

  • We had a discussion over at:
    New joint DHT11/DHT22 9 month ago.
    http://forum.espruino.com/conversations/­281522/

     },20); // time in msec (min 15 virker) 6 20 // PB
    
  • Ok, just updated with a longer timeout.

    Sorry about that @Frida, looks like I missed your suggestion

  • Don't be, we all can't know everything, it's now a big forum, so keep up the good work.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

DHT22 problem

Posted by Avatar for ClearMemory041063 @ClearMemory041063

Actions