Avatar for maze1980

maze1980

Member since Jun 2019 • Last active Nov 2019
  • 7 conversations
  • 110 comments

Most recent activity

  • in ESP32
    Avatar for maze1980

    I guess there is a better way: Do not create new timer every 1000ms, but only once. Just to quote one function:

    //get wifi status every second
    function iw1() {
      wifi_stat = Wifi.getDetails().status;
      //set led blink rate
      if(wifi_stat !== "connected") {led_speed = 100;}
      else {led_speed=500;}
      setTimeout(iw1,1000);
    }
    iw1();
    

    And how to do it better:

    //get wifi status every second
    function iw1() {
      wifi_stat = Wifi.getDetails().status;
      //set led blink rate
      if(wifi_stat !== "connected") {led_speed = 100;}
      else {led_speed=500;}
    }
    iw1();
    setInterval(iw1,1000);
    

    While there is a garbage collection, it might be called too late, or not working properly - I didn't look into it. But if you call setTimeout every 1000ms instead of setInterval once there's a really high chance it'll allocate a new block of memory for a new timer every 1000ms.
    The other functions shall be modified accordingly.

  • in ESP32
    Avatar for maze1980

    The collection of "0"s and "1"s should only be enabled within the expected window

    Why, what's the benefit?
    For me setting the watch once is more effective, as it is only done once. The pin can't be used for anything else but a DHT11 sensor anyway.

    Since multiple sensors can be on a single line

    No. That is impossible. Or did I miss something?

  • in ESP32
    Avatar for maze1980

    Nice rewrite, I really like it. Maybe you could

    1. add pinMode(self.pin, 'input_pullup'); to function DHT11(pin) before setting the watch. In my opinion not having this is the reason that the first bit is zero in the first run, and one in the consecutive runs that you observed (line 15).
    2. replace self.d += 0 | (t.time - t.lastTime > 0.00005); with self.d += Number(t.time - t.lastTime > 0.00005); (line 19).
    3. remove pinMode(self.pin); (line 40). The signal should be pulled all time, line 39 is sufficient.
    4. Remove the 10 consecutive measurements, already done.
    5. fix // Two first bytes are header ... to bits (line 63).
    6. add err: false in the callback for a successful measurement (line 79).
    7. change to temp: undefined, rh: undefined in the callback for a failed measurement (line 89). Because -1 is a valid temperature it's not an optimal return value for a failed measurement, and also not good for further processing (you can store -1 for temp and rh in a database, if you don't test)
    8. Test t, tf, rh, rhf to be numbers before calling parseFloat. If self.d is less than 42 bits the parseInt will eventually return "NaN", so I would suggest to test the length of self.d in line 63.

    5, 6, 7 and 8:

        setTimeout(function() {
            let error = true;
            let temp = undefined;
            let relh = undefined;
            if (self.d.length === 42) { //Only if we got 42 bits
                // Two first bits are header. First bit is 0 on first, 1 on consecutive. Second bit is always 1.
                let h = self.d.substr(1,1);                 // Header, always "1" - we'll include this in checksum test
                let rh = parseInt(self.d.substr(2,8),2);    // Relative humidity
                let rhf = parseInt(self.d.substr(10,8),2);  // Relative humidity fraction
                let t = parseInt(self.d.substr(18,8),2);    // Temperature
                let tf = parseInt(self.d.substr(26,8),2);   // Temperature fraction
                let csum = parseInt(self.d.substr(34,8),2); // Checksum
        
                // Calculate checksum
                let cks = rh + rhf + t + tf;
            
                // Check checksum:
                // - It is not zero (temp and humidity exactly zero?)
                // - Sum all data, compare last byte to checksum byte
                if (h == "1" && cks && ((cks & 0xFF) == csum)) {
                    error = false;
                    temp = parseFloat(t + "." + tf);
                    relh = parseFloat(rh + "." + rhf);
                }
            }
            // Callback
            cb({ err: error, raw: self.d, temp: temp, rh: relh });
        }, 30);
    

    I did't try the code not having a DHT11, watch out for typos and other errors. But I guess you'll get the idea and catch them.
    Anyway, you write the module so do what you need. Others can adjust the code to their needs, as it is now much cleaner and easier to understand compared to the original module.

  • in ESP32
    Avatar for maze1980

    You should set the pin mode in the connect function to pinMode(ht.pin, 'input_pullup');, to avoid random signals to be received.

    And you could replace a code of code as follows, mainly for better comments, from

    ...
      digitalWrite(ht.pin, 0);
      pinMode(ht.pin,"output"); // force pin state to output
      // raise pulse after 1ms
      setTimeout(function() { pinMode(ht.pin, 'input_pullup'); pinMode(ht.pin); }, 20);
      // stop looking after 50ms
    ...
    

    to

    ...
     //pull signal to ground for 20 ms to request data from DHT11
      pinMode(ht.pin,"output");
      digitalWrite(ht.pin, 0);
      setTimeout(function() { pinMode(ht.pin, 'input_pullup'); }, 20);
    
      //parse the received data after 50ms
    ...
    
  • in ESP32
    Avatar for maze1980

    Looks good, just a lil' bit hacked ( var _this = this; and later var ht = this;). I'd keep it the same variable in both lines - I like to use "var self = this;" as it works without underscore.

    Maybe a disconnect function would be nice, to remove the watch when no longer needed. But memory is limited, and I don't think that anyone would ever use it. Unless trying to connect different devices to the same pin, which would be a bad design, better using I2C instead.

  • in ESP32
    Avatar for maze1980

    One thing you could try to identify the bug in the DHT11.js module: Print the read "raw" value, using your code in #1.
    tldr:
    I'd assume it's length differs from the length in #3, having one extra bit. And removing this bit would fix the module for the ESP32, and would break it for all other boards having a different timing. A rewrite of the module with the setup of the watch only once at the "connect" would be the best solution, and should fix it for all platforms.

  • in ESP32
    Avatar for maze1980

    To fix the out-of-memory error, replace these lines (refering to post #3)

    this.watch = setWatch(function(t) {
        if(ht.watch){ ht.watch = clearWatch(ht.watch); }
    

    with these lines

    var w = setWatch(function(t) {
    clearWatch(w);
    

    It would be better to set the watch only once (as well as some other setup tasks), instead of setting it in every run (as it is done in this .js module).

  • in ESP32
    Avatar for maze1980

    Sorry, edited my post. I wanted to say, the DHT11.js software module has most likely a bug, not the hardware.

  • in ESP32
    Avatar for maze1980

    In my opinion a bug in the dht11.js software module. You are not the first to have issues, see also:
    http://forum.espruino.com/conversations/­316733/#comment14104546
    I don't have a fix, and no DHT11 to test.

  • in Espruino Work
    Avatar for maze1980

    Selling ESP could generate some extra cashflow - however at prices starting at USD1.89 in China I can't see a huge volume or margin. And I can't see how it would help to raise popularity.
    If ESP shall be officially supported boards is yet another question.

Actions