nodemcu, esp8266, ds18s20

Posted on
Page
of 2
Prev
/ 2
  • There is no way of knowing if this is a 'real' 85c or the bogus first value

    Ignore first reading since it's always 85C, and report from the next? Assuming you're capturing at intervals a counter var is all needed. Workaround, but works fine for me.

  • I think the DS18B20 module is used a lot, so I'd be against changing something that broke it. Having said that, I doubt many people are using 'verify' so function(callback,verify) would probably be fine.

    I'm not convinced about returning undefined for the first call - if existing code does anything with that value (like an average) you could end up with NaN propagated through the code. I think maybe just keep the behaviour without a callback as-is, but change the documentation to advise people to use the callback.

    To help with that, kicking off a conversion in the constructor sounds like a good plan though.

    although the .js and .min.js would have different hash

    The comment in them would have to show the git hash of the repo at the commit they were made I think.

    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.

    Yeah, it makes sense - I think in Espruino's case there's not as much need for it as in something like NPM though. Generally modules are relatively simple and don't change that much once they're written.

    The current solution is definitely not perfect, but adding NPM style version control (and package.json) adds a lot of complexity. It's a lot to implement, but also a lot to ask users to get to grips with when a lot of Espruino's draw is the simplicity (many users aren't node.js users).

    A bit off topic, but my personal gripe with NPM/Node.js is that because there is a good versioning system, it seems to give people an excuse to make changes to the API all the time. As a result, if you don't have a package.json with versions in then your software probably won't work any more in a year's time, and if you do, you're using out of date modules in most cases. I'm not sure there's a way around it, but it is particularly frustrating having to debug your code every 6 months just to find that someone's renamed a function :(

  • I'm looking at this now... Does anyone actually use verify? It's horrible, and really slow as each reading it'll do a full search of each device.

    I'd imagine that if the device got removed there would be some OneWire error anyway, which could be dealt with.

  • Ok, I've just updated the module. Please could someone try:

    var t = require("https://raw.githubusercontent.c­om/espruino/EspruinoDocs/master/devices/­DS18B20.js").connect(new OneWire(A1));
    t.getTemp(console.log);
    

    And see if it works on DS18S20 as well?

    I hopefully tidied it up a lot so it uses OneWire a bit more efficiently. It also checks the CRC now, so verify isn't needed and has been removed - the minified code is a smidge smaller too.

    Personally I'd be tempted to remove isPresent, since a call to getTemp will just return null now.

  • works for me with DS18B20 devices - had to add for the esp8266:
    A1=NodeMCU.D1;

    or my case change to D5: ( wired to different pin)

    var t = require("https://raw.githubusercontent.c­om/espruino/EspruinoDocs/master/devices/­DS18B20.js").connect(new OneWire(D5));
    t.getTemp(console.log);
    
    WARNING: the esp8266 port is in beta!
    Flash map 4MB:512/512, manuf 0xe0 chip 0x4016
    >echo(0);
    =undefined
    25.75
    > 
    

    I'll test the callback soon, and have some questions on how this will work multiple sensors.

    Can we start a conversion on all sensors, and then have a callback with all temps?

    I'm not sure if the current callback identifies the device, I'll set up some test cases.

  • The callback needs some sort of identifier, as you can't assume the order of the readings in the callbacks. I have two sensors connected:

    var pin=D5; // update for your hardware!
    var ow = new OneWire(pin);
    
    ds = require("https://raw.githubusercontent.c­om/espruino/EspruinoDocs/master/devices/­DS18B20.js");
    
    function cb(t) {  
      print({cb_temp:t});
    }
    var s=ow.search();
    
    console.log( { search:s } );
    
    var sensors = s.map(function (device) {
      return ds.connect(ow, device);
    });
    
    setInterval(function() {
       sensors.forEach(function (sensor, index) {
          console.log(index + ": " + sensor.getTemp(cb));
      });
    },2000);
    
    {
      "search": [
        "28cc2e230500006b",
        "283260dc04000001"
       ]
     }
    =undefined
    0: undefined
    1: undefined
    { "cb_temp": 25.8125 }
    { "cb_temp": 24.9375 }
    0: undefined
    1: undefined
    { "cb_temp": 25.8125 }
    { "cb_temp": 24.9375 }
    0: undefined
    1: undefined
    

    There are a couple of options:

    if (callback) callback(temp);

    if (callback) callback(this);
    function cb(t) {
    print({cb_temp:t.getTemp()});
    }

    if (callback) callback(temp,this.sCode);

    or probably most flexible:

    if (callback) callback(temp,this);
    And then you have the object if you need it...

    1. Should getTemp return the last value, even with a callback, rather than undefined?

    2. here is how to avoid the intial bogus value:

      var sensors = s.map(function (device) {
      var t=ds.connect(ow, device);
      t.getTemp();
      return t;
      });
      
      sensors.forEach(function (sensor, index) {
        console.log('initial' + ": " + sensor.getTemp());
      });
      

    This could be done automagically in the constructor here:

      this.type=parseInt(this.sCode[0]+this.sC­ode[1]);
      this.getTemp(); // trigger a conversion
    }
    
  • or not ;-(

    After re-powering the board, the sensors reverted to the 85C state:

      "search": [
        "28cc2e230500006b",
        "283260dc04000001"
       ]
     }
    initial: 85
    initial: 85
    =undefined
    0: undefined
    1: undefined
    { "cb_temp": 26.3125 }
    

    I guess if you executed other code before the first actual call to getTemp() this would work out ok....

    By setting the mode to 9 bit so the conversion is shorter:

    var sensors = s.map(function (device) {
      var t=ds.connect(ow, device);
      t.setRes(9);
      t.getTemp();
      t.setRes(12);
      return t;
    });
    
    {
      "search": [
        "28cc2e230500006b",
        "283260dc04000001"
       ]
     }
    initial: 25.4375
    initial: 24.0625
    =undefined
    0: undefined
    1: undefined
    { "cb_temp": 25.875 }
    { "cb_temp": 24.9375 }
    
  • @Wilberforce I think it's best not to worry about the initial value - people have been using this DS18B20 module for years and are happy to just put up with it.

    Producing a good first value half the time is worse than never doing it :)

    Should getTemp return the last value, even with a callback, rather than undefined?

    I don't think so... It's another request over OneWire and more calculation that will never be used most of the time...

    The callback needs some sort of identifier, as you can't assume the order of the readings in the callbacks.

    I don't think so - you can easily re-write your code:

       sensors.forEach(function (sensor, index) {
          sensor.getTemp(function(temp) {
            console.log(index + ": " + temp));
          });
      });
    

    And there are plenty of other ways to do this that don't require changes in the module.

  • Thanks Gordon.

    Here is the code modified to save the results to an array, updating every 1/2 sec and displaying every sec:

    var pin = D5; // update for your hardware!
    var ow = new OneWire(pin);
    ds = require("https://raw.githubusercontent.c­om/espruino/EspruinoDocs/master/devices/­DS18B20.js");
    
    var s = ow.search();
    console.log({
      search : s
    });
    var sensors = s.map(function (device) {
        return ds.connect(ow, device);
      });
    
    var temps = [];
    setInterval(function () {
      sensors.forEach(function (sensor, index) {
        sensor.getTemp(function (temp) {
          temps[index] = temp;
        });
    
      });
    }, 500);
    
    setInterval(function () {
      console.log(temps);
    }, 1000);
    
    {
      "search": [
        "28cc2e230500006b",
        "283260dc04000001"
       ]
     }
    =undefined
    [  ]
    [ 24.5, 24.4375 ]
    [ 24.5625, 24.4375 ]
    [ 24.5, 24.4375 ]
    [ 24.5, 24.4375 ]
    
  • Messing around with this sketch and nodemcu amica board. Spent a lot of time on debug and finally got the issue, nodemcu pinout didn't match esp8266 mounted on it (for example D2(esp) => D4(amica)).

  • Try using NodeMCU.D4 instead of D4?

  • @Gordon thank you! It works.
    I've tried to find mapping but in a tve's repo. Esp now is officially supported and code is in main repo, right?

    I'm so happy I found espruino, I really like it! Thank you!

    Is there any way to store short data counters using inner memory?
    I've tied FlashEEPROM, but it seems not working. Because of esp8266?
    Module looking for flash_start and flash_length properties inside process.memory() object,
    but there is nothing. It is specific of esp?

  • Yes, ESP8266 should now be in the main repo - @tve is probably still doing some development in his, but he generally syncs everything up with the main repo.

    FlashEEPROM does work, but you have to manually specify an address for it. You should be able to use: http://www.espruino.com/Reference#l_ESP8­266_getFreeFlash to find one.

    It's something that'll hopefully change soon - we'll add a function to get free flash pages that works on all platforms.

  • @Gordon getFreeFlash() will calculate a next free address or returns user flash area of specific platform? I'm trying to get if it returns same results on each run or increasing address depending on usage? Sorry for lame questions I'm noob here.

  • It just returns the addresses of unused areas of flash memory - they're the same each time, so you can just do var f = new (require("FlashEEPROM"))(ESP8266.getFree­Flash()[0].addr); I think

  • @Gordon it works but property called area not addr, and it bricked nodemcu with [0], won't boot on the next run and after reflashing. I've manage to fix it by flashing blank512kb.bin twice.
    I'm curious maybe it's better to use [1] or [2], getFreeFlash() returns 3 areas for esp8266?
    Thanks anyway!

  • Wow, that's not good. @tve? Maybe we could put the pages in a different order?

    I noticed yesterday about the odd naming - it didn't match the docs either. I've now fixed it though, so 1v86 will be better when it is released (and FlashEEPROM should work automatically)

  • The areas [0] and [1] are tiny from memory. I have used the area[2] but I think that is only 3 pages of 4096 bytes long.

  • There is a 16kb block here if you have > 512 kb device -
    0x07C000 496KB 16KB 512KB flash: Espressif SDK system params, else unused

    There is some conversation around this on gitter
    https://gitter.im/espruino/Espruino

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

nodemcu, esp8266, ds18s20

Posted by Avatar for hygy @hygy

Actions