nodemcu, esp8266, ds18s20

Posted on
Page
of 2
/ 2
Next
  • Hi,

    I'm trying to wire up a nodemcu with ds18s20, but it is not found the sensor. DS18S20 is connected to 3.3V and GND between the 3.3V and DATA line I connected a 4k7 resistor. Data line connected to ~D3 port (pin0).

    What i'm doing wrong?

    var GPIO0 = new Pin(0); // GPIO0 | ~D3 port
    
    var ow = new OneWire(GPIO0);
    
    var sensor = require("DS18B20").connect(ow);
    
    console.log('sensor getting data');
    
    setInterval(function() {
      console.log(sensor.getTemp());
    }, 1000);
    

    I'm getting null for sensor.getTemp();

    >ow.search();
    =[  ]
    

    thanks,
    HyGy

  • @Kolban does OneWire work on ESP8266? I thought I'd seen that someone had got it working?

    Have you tried a different pin? GPIO0 could be one of the pins that is used for something else.

  • Yes. I tried other pins too.

  • @Kolban there is no OneWire support yet in esp8266?

  • I had Onewire working fine on ESP8266 last week though I needed to add

    require("ESP8266").logDebug(false);
    

    before my code. I believe this is only while the ESP8266 port is in development, when complete this will be set off by default.

  • Wow, i2c started to work. I can list the devices.

    But the values are wrong with ds18s20. Its always writes the same value: 10.6875 and it is not changing. :(

    How do I know when I can remove this line from the code?

  • How do I know when I can remove this line from the code?

    That's one for @kolban I don't know - though I don't imagine leaving the code in will do any harm even when the default is set to false.

    Re your readings I got good readings on the ESP8266-1. Maybe try another temperature probe - I note you say DS18S20? I used the DS18B20. One thing I found useful was to mirror or replicate the setup on a Pico - especially since the DS18B20 wire colour coding seems to vary! Once I sussed the wiring on a Pico, I then knew what to expect on the ESP8266.

  • The ds18b20 and s20 are differs for reading mode as I know. The wiring is good, couse I can read the onewire device id (if I connect more then one, then all the readings).

  • It is time to change the debugging to a default of "off". Sorry about that guys ... next set of builds will have debug off by default.

  • @Kolban thanks. Can U check the ds18s20 problem too?

  • I'll be delighted to .... however it might be a few days (weekend likely) before I can get to it. Do you use the gitter stream in case I need to ask you some live questions?

  • @Kolban If U give me a documentation where can U found this gitter stream, I use it then to help you. Its like google hangouts?

  • Espruino Gitter room here

    https://gitter.im/espruino/Espruino

  • Thanks! I connected.

  • You may need a smaller pull-up resistor, maybe 2.2K. I tried a ds18b20 two days ago and it didn't work and I don't understand why, but it was working a couple of weeks ago. Maybe the logging is the issue, I didn't check that.

  • Forgot to add, looking at the DS18B20 module, the code does not wait for the temperature conversion to complete, so I think you will always get the old conversion. It's not a very good module, IMHO...

  • I made some fixes to the built-in OneWire module to support parasitically powered one-wire devices. The old code wasn't providing enough power to perform temperature conversions: a DS18B20 uses 1mA-1.5mA during conversion and that's not going to come through a 2.2K or 4.7KOhm pull-up resistor. This change would have no effect on powered 1-wire devices.

    There's also a bug in the DS18B20 JS module in that it doesn't wait for the conversion to finish. I'm pretty sure that the effect is that one gets the result of the previous conversion, which may be why people have not noticed.

    WRT the DS18S20 the temperature format is slightly different from the DS18B20, so some adaptation of the code is necessary. I believe that multiplying the result by 8 will so the trick, but I'm not sure.

    If anyone has trouble with parasitically powered DS18B20's and wants to try my esp8266-12 firmware let me know. I'll create a pull request for master in a few days as there are a few more improvements I'd like to make to the code.

  • It'd be great if the OneWire changes could help with parasitically-powered devices... I did try at some point in the past and couldn't get it working...

    Do you have a Pico and/or original board you could test the changes out with? I guess it should be the same on your EMW port though.

    Yes, the DS18B20 module isn't great... Any idea how long the conversion takes? If it's anywhere near 1ms it should probably use a callback though.

  • At the weekend I changed a little bit the ds18b20 code: Now it works for me with ds18s20 too, and it waits for 1 sec to a conversation and then calls a given callback.

    It's based on @tve modification.

    var C = {
        CONVERT_T: 0x44,
        COPY: 0x48,
        READ: 0xBE,
        WRITE: 0x4E
    };
    
    function DS18B20(oneWire, device) {
        this.bus = oneWire;
        if (device === undefined) {
            this.sCode = this.bus.search()[0];
        } else {
            if (parseInt(device).toString() == device && device >= 0 && device <= 126) {
                this.sCode = this.bus.search()[device];
            } else {
                this.sCode = device;
            }
        }
        this.deviceTypeCode=parseInt(this.sCode[­0]+this.sCode[1]);
    }
    
    /** For internal use - read the scratchpad region */
    DS18B20.prototype._readSpad = function(convert_t) {
    
        var spad = [];
        this.bus.reset();
        this.bus.select(this.sCode);
        convert_t=false;
        if (convert_t) {
    
            this.bus.write(C.CONVERT_T, true);
            this.bus.reset();
            this.bus.select(this.sCode);
        }
        this.bus.write(C.READ);
        for (var i = 0; i < 9; i++) {
            spad.push(this.bus.read());
        }
        return spad;
    };
    
    /** For internal use - write the scratchpad region */
    DS18B20.prototype._writeSpad = function(th, tl, conf) {
        this.bus.reset();
        this.bus.select(this.sCode);
        this.bus.write(C.WRITE);
        this.bus.write(th);
        this.bus.write(tl);
        this.bus.write(conf);
        this.bus.reset();
        this.bus.select(this.sCode);
        this.bus.write(C.COPY);
        this.bus.reset();
    };
    
    /** Set the resolution in bits. From 8 to 12 bits */
    DS18B20.prototype.setRes = function(res) {
        var spad = this._readSpad();
        res = [0x1F, 0x3F, 0x5F, 0x7F][E.clip(res, 9, 12) - 9];
        this._writeSpad(spad[2], spad[3], res);
    };
    
    /** Return the resolution in bits. From 8 to 12 bits */
    DS18B20.prototype.getRes = function() {
        return [0x1F, 0x3F, 0x5F, 0x7F].indexOf(this._readSpad()[4]) + 9;
    };
    
    /** Return true if this device is present */
    DS18B20.prototype.isPresent = function() {
        return this.bus.search().indexOf(this.sCode) !== -1;
    };
    
    /** Get a temperature reading, in degrees C */
    DS18B20.prototype.getTempOld = function(verify) {
    
        var spad = null;
        var temp = null;
        if ((verify && !this.isPresent()) || !this.sCode) {
            return temp;
        }
        spad = this._readSpad(true);
    
        temp = spad[0] + (spad[1] << 8);
        if (temp > 32767) {
            temp -= 65536;
        }
        temp = temp / 16.0;
        return temp;
    };
    
    DS18B20.prototype.getTemp = function(callback) {
    
        var me=this;
        var temp=null;
        var spad=null;
    
      ow.reset();
      ow.select(this.sCode);
      ow.write(C.CONVERT_T, true);
    
      setTimeout(
        function() {
          var s = sensor._readSpad(false);
          var str="";
          s.forEach( function(v) { str+=" 0x"+v.toString(16); } );
          var temp = s[0] + (s[1]<<8);
          if (temp > 32767) temp -= 65536;
    
          switch (me.deviceTypeCode)
          {
            case 10:
               temp = temp/2.0;
                break;
            default:
              temp = temp/16;
              break;
          }
          callback(temp);
        },
        1000);
    }
    
    /** Return a list of all DS18B20 sensors with the alarms set */
    DS18B20.prototype.searchAlarm = function() {
        return this.bus.search(0xEC);
    };
    
    /** Set alarm low and high values in degrees C - see DS18B20.prototype.searchAlarm.
      If the temperature goes below `lo` or above `hi` the alarm will be set. */
    DS18B20.prototype.setAlarm = function(lo, hi) {
        lo--; // DS18B20 alarms if (temp<=lo || temp>hi), but we want (temp<lo || temp>hi)
        if (lo < 0) lo += 256;
        if (hi < 0) hi += 256;
        var spad = this._readSpad();
        this._writeSpad(hi, lo, spad[4]);
    };
    
    /** Initialise a DS18B20 device. Use either as:
      connect(new OneWire(pin)) - use the first found DS18B20 device
      connect(new OneWire(pin), N) - use the Nth DS18B20 device
      connect(new OneWire(pin), ID) - use the DS18B20 device with the given ID
     */
    exports.connect = function(oneWire, device) {
        return new DS18B20(oneWire, device);
    };
    
    
  • I want to know that if OneWire work with the ESP8266? As per my observation someone had got it working?
    You must try a different pin. GPIO could be one of the pins that is used for something else.
    One thing you must try to mirror or replicate the setup on a Pico.

  • Here's my modified @hygy code. I set Timeout depending on Thermometer Resolution and Max Conversion Time. Tested on DS18B20 and ESP-12q. Can someone check and update code DS18B20.js ?

    /*
    Module for the DS18B20 temperature sensor
    
    var ow = new OneWire(A1);
    var sensor = require("DS18B20").connect(ow);
    sensor.getTemp(function (temp) {    console.log("Temp is "+temp+"°C");  }, true);
    sensor.setRes(9);
    sensor.getTemp(function (temp) {    console.log("Temp is "+temp+"°C");  }, true);
    var sensor2 = require("DS18B20").connect(ow, 1);
    var sensor3 = require("DS18B20").connect(ow, -8358680895374756824);
    
    */
    
    var C = {
        CONVERT_T: 0x44,
        COPY: 0x48,
        READ: 0xBE,
        WRITE: 0x4E
    };
    
    function DS18B20(oneWire, device) {
        this.bus = oneWire;
        if (device === undefined) {
            this.sCode = this.bus.search()[0];
        } else {
            if (parseInt(device).toString() == device && device >= 0 && device <= 126) {
                this.sCode = this.bus.search()[device];
            } else {
                this.sCode = device;
            }
        }
        this.deviceTypeCode=parseInt(this.sCode[­0]+this.sCode[1]);
    }
    /** For internal use - read the scratchpad region */
    DS18B20.prototype._readSpad = function() {
        var spad = [];
        this.bus.reset();
        this.bus.select(this.sCode);
        this.bus.write(C.READ);
        for (var i = 0; i < 9; i++) {
            spad.push(this.bus.read());
        }
        return spad;
    };
    /** For internal use - write the scratchpad region */
    DS18B20.prototype._writeSpad = function(th, tl, conf) {
        this.bus.reset();
        this.bus.select(this.sCode);
        this.bus.write(C.WRITE);
        this.bus.write(th);
        this.bus.write(tl);
        this.bus.write(conf);
        this.bus.reset();
        this.bus.select(this.sCode);
        this.bus.write(C.COPY);
        this.bus.reset();
    };
    /** Set the resolution in bits. From 8 to 12 bits */
    DS18B20.prototype.setRes = function(res) {
        var spad = this._readSpad();
        res = [0x1F, 0x3F, 0x5F, 0x7F][E.clip(res, 9, 12) - 9];
        this._writeSpad(spad[2], spad[3], res);
    };
    /** Return the resolution in bits. From 8 to 12 bits */
    DS18B20.prototype.getRes = function() {
        return [0x1F, 0x3F, 0x5F, 0x7F].indexOf(this._readSpad()[4]) + 9;
    };
    /** Return true if this device is present */
    DS18B20.prototype.isPresent = function() {
        return this.bus.search().indexOf(this.sCode) !== -1;
    };
    /** Get a temperature reading, in degrees C */
    DS18B20.prototype.getTemp = function(callback,verify) {
      if ((verify && !this.isPresent()) || !this.sCode) {
        return callback(null);
      }
      var tim = {9:94, 10:188, 11:375, 12:750}; //Thermometer Resolution (bit) : Max Conversion Time (ms)
      this.bus.reset();
      this.bus.select(this.sCode);
      this.bus.write(C.CONVERT_T, true);
      setTimeout(
       function(me) {
        var s = me._readSpad();
        var str="";
        s.forEach( function(v) { str+=" 0x"+v.toString(16); } );
        var temp = s[0] + (s[1]<<8);
        if (temp > 32767) temp -= 65536;
        switch (me.deviceTypeCode){
         case 10: temp = temp/ 2.0; break;
         default: temp = temp/16.0; break;
        }
       callback(temp);
      }, tim[this.getRes()], this);
    }
    /** Return a list of all DS18B20 sensors with the alarms set */
    DS18B20.prototype.searchAlarm = function() {
        return this.bus.search(0xEC);
    };
    /** Set alarm low and high values in degrees C - see DS18B20.prototype.searchAlarm.
      If the temperature goes below `lo` or above `hi` the alarm will be set. */
    DS18B20.prototype.setAlarm = function(lo, hi) {
        lo--; // DS18B20 alarms if (temp<=lo || temp>hi), but we want (temp<lo || temp>hi)
        if (lo < 0) lo += 256;
        if (hi < 0) hi += 256;
        var spad = this._readSpad();
        this._writeSpad(hi, lo, spad[4]);
    };
    /** Initialise a DS18B20 device. Use either as:
      connect(new OneWire(pin)) - use the first found DS18B20 device
      connect(new OneWire(pin), N) - use the Nth DS18B20 device
      connect(new OneWire(pin), ID) - use the DS18B20 device with the given ID
     */
    exports.connect = function(oneWire, device) {
        return new DS18B20(oneWire, device);
    };
    
  • Is there a way of making this backward compatible with the existing library?

    So instead of:

    DS18B20.prototype.getTemp = function(callback,verify) {   if ((verify && !this.isPresent()) || !this.sCode) {
    

    Will this work with older code:

    console.log(sensor.getTemp());
    

    So if the callback is missing, it will wait and return?

    Which leads to this question.. There is no versioning in modules, so if the library code was updated there is no easy way to tell if an update has been made.

    Would a simple 1.2 type version number in the module header suffice?

  • Maybe... Busy-waiting is a really bad idea in Espruino though.

    The best bet would be to return the last temp reading if no callback was supplied (the current behaviour), and if there was a callback, to kick off a new reading, wait and return that.

    The code above waits 1 second for the callback - seems pretty extreme? I doubt many people would be happy with that.

    I'm still a bit confused here - does the existing DS18B20 library not work with ESP8266? My understanding was just that the current one was fine, but it just returned the previous reading (which means the first one returns 85 or something like that).

    There is no versioning in modules, so if the library code was updated there is no easy way to tell if an update has been made.

    Well, there's GitHub's versioning? Each version of each module has a unique Git hash. I guess that could be added to each module in espruino.com/modules?

    Then if you want to go back to a certain version, pull it straight off GitHub, eg: require("https://raw.githubusercontent.c­om/espruino/EspruinoDocs/47ca0f6b2ba6076­62071822f115cf3a3b57f5d93/devices/DS18B2­0.js")

    Would a simple 1.2 type version number in the module header suffice?

    Maybe. What do you expect to do with it though? Most people won't look at the module number until something goes wrong, and then it's too late. How would you then work back to find the older version?

  • I modifed this code originally, couse the original is doesnot work with ds18s20 just with 18b20.

  • @Gordon
    There are a few things going on in this thread!

    I'm still a bit confused here - does the existing DS18B20 library not work with ESP8266? My understanding was just that the current one was fine, but it just returned the previous reading (which means the first one returns 85 or something like that).

    a. Yes - the code works on the ESP8266

    b. Add support ds18s20 as well as ds18s20

    @hygyI modifed this code originally, cause the original is does not work with ds18s20 just with 18b20.

    c. Callback

    @gordon The code above waits 1 second for the callback - seems pretty extreme? I doubt many people would be happy with that.

    The time it takes for a conversion depends on the resolution and if parasitic mode mode is in use.
    http://forum.espruino.com/comments/12612­450/
    The modified code #21 http://forum.espruino.com/comments/12729­356/ takes the resolution into account so, the callback is no longer 1 sec, but depends on the resolution

    d. One of the issues with the original code is that the initial reading is bogus. The device returns all 111111's, and this turns out to be a value of 85c. For the next call, the real value is in place as the conversion is done. There is no way of knowing if this is a 'real' 85c or the bogus first value

    One solution would be to return undefined until the first conversion is done.
    Another, the constructor could be modified to starts a conversion, so that by the time the first call is made to getTemp, however this could not be guaranteed.

    e. The original code has function getTemp(verify) - Gets the temperature reading.
    the proposed code has function(callback,verify)

    So existing code that use getTemp with verify used would fails as the first param is now a callback.
    I have not idea how widespread this usage is, however I believe the getTemp should work for older code without having to change params.

    f. versioning
    The git hash is a good idea, although the .js and .min.js would have different hash, even though they are a 'pair'. If the .js source had a hash comment, at least local projects and SD card modules would have the version details in them.
    The idea of the x.y notation like used in node is that if a function signature changes (like e above), the major number x would be incremented to indicate. However without package.json this would not be of much benefit ;-(

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

nodemcu, esp8266, ds18s20

Posted by Avatar for hygy @hygy

Actions