New joint DHT11/DHT22 module

Posted on
Page
of 4
/ 4
Last Next
  • Hi,

    It's come up in another thread that the existing DHT11 & 22 modules aren't that fast or memory efficient. There's been a pull request for a multipurpose module, but it's still slower than it could be, and doesn't work in a backwards-compatible way with DHT11.

    I don't have a DHT22 here so can't test, but maybe someone else could take a look at this and see if it works on all the various different module types, or whether we need a few more tweaks?

    // Sensor object constructor
    function HT(device, pin) {
      this.device = device;
      this.pin = pin;
    }
    
    // sensor query method...
    /** read sensor as either...
      read(callback);
      read(callback,number_of_tries); - default=3
      */
    HT.prototype.read = function (cb,n) {
      if (!n) n=3;
      var d = ""; 
      var ht = this;
      pinMode(ht.pin); // set pin state to automatic
      digitalWrite(ht.pin,0);
      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);
        if (cks&&((cks&0xFF)==parseInt(d.substr(34,­8),2))) {
          var o = { raw:d };
          if (ht.device=="DHT11") {
            o.rh = parseInt(d.substr(2,8),2);
            o.t = parseInt(d.substr(18,8),2);
          } else {
            o.rh = parseInt(d.substr(2,16),2)*0.1;
            o.t = parseInt(d.substr(19,15),2)*0.2*(d[16]-0­.5);
          }
          cb(o);
        } else {
          if (n>1) setTimeout(function() {ht.read(cb,--n);},500);
          else cb({err:true, raw:d});
        }
      },6);
    };
    
    // Test with
    var dht = new HT("DHT11",A8);
    dht.read(print);
    

    I can then put it into a HTxx module, and can reference that from existing DHT11/22 modules to provide a seamless upgrade for everyone already using them.

  • Why wouldn't we keep separate modules, keep the API the same, and get rid of the old DHTxx modules, if this works and is faster?

    This would make the module take up a couple fewer jsvars too, which is an issue that you have to keep in mind since we don't have a compiler to optimize out unreachable code like we do on Arduino - this weakens the argument for "one library that does a whole bunch of devices" paradigm.

  • Yes, I was starting to think that - the code itself is quite simple, and the duplication is probably worth it to simplify things.

    I guess it depends whether there are any other differences between them apart from just DHT11 and DHT22?

  • Please can someone test this on DHT22? Then both modules can be updated to use the more efficient code.

  • I'll try to test on mine this weekend.

  • I will test too over the weekend

  • working fine on ESP, build version see test output

    comments: I prefer a fixed result format, e.g. 999.9

    pin=D4;
    // latest version 14-Jan-2016 16:09
    var dht22 = require("DHT22").connect(pin);
    
    var dht22_read_test = function() {
      dht22.read(
        function(a){
          console.log("Temp is "+a.temp.toString()+
                      " and RH is "+a.rh.toString());
    });};
    
    setInterval(dht22_read_test,5000);
    
    
    /* test output 
    
     1v84.tve_master_f35ac96 Copyright 2016 G.Williams
    WARNING: the esp8266 port is in beta!
    Flash map 4MB:512/512, manuf 0xe0 chip 0x4016
    >echo(0);
    =undefined
    Temp is 19.9 and RH is 45.7
    Temp is 19.9 and RH is 45.8
    Temp is 19.9 and RH is 45.6
    Temp is 19.9 and RH is 45.6
    Temp is 19.9 and RH is 45.6
    Temp is 19.9 and RH is 46
    Temp is 19.9 and RH is 43.1
    Temp is 19.8 and RH is 42.3
    Temp is 19.8 and RH is 40.8
    Temp is 19.7 and RH is 40.9
    Temp is 19.5 and RH is 41.3
    Temp is 19.4 and RH is 41.3
    Temp is 19.2 and RH is 39.5
    Temp is 19.1 and RH is 40.3
    Temp is 18.9 and RH is 43.7
    Temp is 18.7 and RH is 44.2
    Temp is 18.2 and RH is 36.9
    Temp is 17.9 and RH is 37.2
    Temp is 17.7 and RH is 39.1
    Temp is 17.4 and RH is 36.7
    Temp is 17 and RH is 36.4
    Temp is 16.6 and RH is 37.4
    Temp is 16.3 and RH is 38.9
    Temp is 15.9 and RH is 41.1
    Temp is 15.6 and RH is 42
    Temp is 15.3 and RH is 41
    Temp is 14.8 and RH is 42.9
    Temp is 14.8 and RH is 42.9
    Temp is 14.6 and RH is 43.5
    */
    
    
  • That's good to know... @MaBe have you tried a.rh.toFixed(1)? That should output with the given number of decimal places.

  • yes, that's it - thanks.

          console.log("Temp is "+a.temp.toFixed(1).toString()+
                      " and RH is "+a.rh.toFixed(1).toString());
    /*
    Temp is 21.1 and RH is 38.9
    Temp is 21.0 and RH is 38.9
    Temp is 21.0 and RH is 39.0
    Temp is 20.9 and RH is 39.1
    */
    
  • @MaBe I've just committed some code specifically for DHT22 - please could you give it a test?

    // DHT22
    var dht = require("https://raw.githubusercontent.c­om/espruino/EspruinoDocs/master/devices/­DHT22.js").connect(pin);
    // or use "https://raw.githubusercontent.com/espru­ino/EspruinoDocs/master/devices/DHT11.js­" for DHT11
    
    setInterval(function() {
      dht.read(
        function(a){
          console.log("Temp is "+a.temp.toString()+
                      " and RH is "+a.rh.toString());
    });}, 5000);
    
  • @Gordon sure, will run some test on Thursday

  • test results for code above on ESP8266

    Temp is -22.3 and RH is 35.7
    Temp is -22.3 and RH is 36
    Temp is -22.3 and RH is 36
    Temp is -22.3 and RH is 36
    

    ESP8266 hint: require("ESP8266").setCPUFreq(80);

  • So there is something wrong? Or is it really that cold where you are? :)

  • sorry, should show +22.3 and not -22.3

  • So is it actually showing the right thing, or is it broken?

  • old version shows 22.3 and new -22.3

  • Can you try now? Should be fixed :)

  • sometimes still returning negative temperature values with that module version, would say this is a ESP specific thing, will try by tomorrow again with a pico

    =undefined
    Temp is 23.9 and RH is 34.8
    Temp is -23.9 and RH is 34.6
    Temp is 23.9 and RH is 34.5
    Temp is -23.9 and RH is 34.3
    Temp is -23.9 and RH is 34.2
    Temp is -23.9 and RH is 34.2
    Temp is 23.9 and RH is 34.1
    Temp is 23.9 and RH is 34
    Temp is 23.9 and RH is 34
    Temp is -23.9 and RH is 33.8
    Temp is -23.9 and RH is 33.8
    >reset();
    
  • Modify the module to print out the raw data it receives. That has been very useful to me when I did the first version of the DHT libraries.

  • good point, using the old version all values look correct

    Temp is 24.6 and RH is 33
    Temp is 24.6 and RH is 32.7
    Temp is 24.6 and RH is 32.8
    Temp is 24.6 and RH is 32.7
    Temp is 24.6 and RH is 32.6
    Temp is 24.6 and RH is 32.5
    Temp is 24.6 and RH is 32.6
    >reset();
    
  • What raw data does it think it's getting? Might have to actually print the times.

  • downloaded module and added print raw value

    raw value:0100000001010001010000000011110110­00111100
    Temp is 24.6 and RH is 32.5
    raw value:0100000001010010000000000011110110­00111111
    Temp is 24.6 and RH is 32.8
    raw value:0100000001010001000000000011110101­00111010
    Temp is 24.5 and RH is 32.4
    raw value:0100000001010000110000000011110101­00111001
    Temp is -24.5 and RH is 32.3
    raw value:0100000001010000100000000011110101­00111000
    Temp is -24.5 and RH is 32.2
    raw value:0100000001010000100000000011110101­00111000
    Temp is -24.5 and RH is 32.2
    raw value:0100000001010000010000000011110101­00110111
    Temp is 24.5 and RH is 32.1
    raw value:0100000001010000010000000011110101­00110111
    Temp is 24.5 and RH is 32.1
    raw value:0100000001010000000000000011110101­00110110
    Temp is 24.5 and RH is 32
    raw value:0100000001001111100000000011110101­00110100
    Temp is -24.5 and RH is 31.8
    raw value:0100000001001111110000000011110101­00110101
    Temp is -24.5 and RH is 31.9
    raw value:0100000001001111110000000011110101­00110101
    Temp is -24.5 and RH is 31.9
    >reset();
    
  • Hmm, I guess it's possible that it's checking the wrong bit to get the sign information?

  • So I just looked, and at the moment it's using parseInt(d.substr(19,15),2)*0.2*(0.5-d[1­6]) - where d is the raw value.

    Maybe you could try the following with the raw data you're getting and see if it works correctly? parseInt(d.substr(19,15),2)*0.2*(0.5-d[1­8])

  • d[18] === d.charCodeAt(18) ? ...feel a bit... (I do not want to say it). ;-)

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

New joint DHT11/DHT22 module

Posted by Avatar for Gordon @Gordon

Actions