• Hello all,
    I'm continuing my trip in the Espruino world and I'm experiencing a problem with the DS18B20 temperature sensor and my ST NUCLEO-F401RE board on which I uploaded the latest version of Espruino (1v93).
    Using the first example shown on the DS18B20 sensor page (http://www.espruino.com/DS18B20) precisely:

    var ow = new OneWire(A0);
    var sensor = require("DS18B20").connect(ow);
    setInterval(function() {
      sensor.getTemp(function (temp) {
        console.log("Temp is "+temp+"°C"); 
      });
    }, 1000);
    
    

    I get the following result (instead of temperature value):

    _____                 _
    |   __|___ ___ ___ _ _|_|___ ___
    |   __|_ -| . |  _| | | |   | . |
    |_____|___|  _|_| |___|_|_|_|___|
              |_| http://espruino.com
     1v93 Copyright 2016 G.Williams
    Espruino is Open Source. Our work is supported
    only by sales of official boards and donations:
    http://espruino.com/Donate
    >
    =undefined
    Temp is null°C
    Temp is null°C
    Temp is null°C
    Temp is null°C
    
    

    The DS18B20 "cabled sensor" type is that identified on the Espruino web page as "Sensor type 1" connected as follows:

    Black wire -> GND
    Red wire -> 3.3V
    Yellow wire -> Data pin (A0)

    I'm also using the 4.7k resistor between data and the 3.3v line as suggested.

    Browsing in the forum before posting the question I noticed the following post:
    http://forum.espruino.com/conversations/­254655/#comment11813806

    in which Gordon suggested to skip the DS18B20 module and search for the sensor through the OneWire protocol.
    In the same configuration (board+sensor), described above, I get the following result:

    >var ow = new OneWire(A0);
    =OneWire { "pin": A0 }
    >ow.search(); // should return an array of devices
    =[
      "28ff050b85160520"
     ]
    > 
    

    It seems to recognize the serial number of the DS18B20 device...

    Could you please help me to solve this issue?
    Thanks in advance for your support.
    Kind regards

  • I cannot see any issue with the code, and with the hardware connectivity things look right the way you describe. I do though not know how serial numbers should look like... (length seems though to be correct: 64 bits... but is there some crc or checksum bit(s) in it?)

    First, I would try with a different pin.

    You may also try to watch the data pin with another pin and use simple watch or Waveform class... (best is to use a separate board for that to have no interference...

    Another option is to replace the sensor... today's cheapos do not always as shiny as they look... (see this dud... fetched from the mechanical world).

    Both, watch and Waveform use buffers which allow the oneWire to finish his job and then deferred you code can do an analysis. Setup a setWatch (with no / 0 debounce) then fire one wire communication, or setup Waveform for input and then fire one wire communicaiton. Even though you may not capture all info - because the one wire is pretty fast - you may get something, and you may even get timing errors... at least indicator that something is going on with some issue...

  • Hello allObjects,
    thanks a lot for your feedback.
    Before trying the example code with Espruino and the DS18B20 module, I tested the very same configuration (e.g. Nucleo Board + 4.7K Resistor + Sensor) using another "native" program and I get the correct temperature.

    Moreover, the same sensor was also tested using an Arduino board and a sample sketch that use the oneWire protocol commands; I get (and convert) the temperature without problems and read the same serial number of the device as returned by Espruino.

    Based on these results I can not say that the sensor itself is damaged or not working...

    Unfortunately, using Espruino and Nucleo Board I can only read the sensor 64-bit serial code through the function OneWire.search() API.
    According to the DS18B20 device user manual, the retrieved code is correct since the last CRC byte (0x20) is properly calculated.
    The possibility to read such number is for me a clue that, "electrically" the OneWire interface links are fine, but any subsequent attempt to read the device memory (scratchpad) or start a temperature conersion\reading cycle through protocol commands is unsuccessful (see below):

     _____                 _
    |   __|___ ___ ___ _ _|_|___ ___
    |   __|_ -| . |  _| | | |   | . |
    |_____|___|  _|_| |___|_|_|_|___|
              |_| http://espruino.com
     1v93 Copyright 2016 G.Williams
    Espruino is Open Source. Our work is supported
    only by sales of official boards and donations:
    http://espruino.com/Donate
    >var ow = new OneWire(A0);
    =OneWire { "pin": A0 }
    >device = ow.search()[0]; // search returns an array of device IDs
    ="28ff050b85160520"
    >ow.reset();
    =true
    >ow.select(device);
    =undefined
    >ow.write(0xBE); // Read Scratchpad [BEh]
    =undefined
    >var result = ow.read(9);
    =new Uint8Array([255, 255, 255, 255, 255, 255, 255, 255, 255])
    > 
    

    Definitely I think I'm losing something when, after I get the device serial number (address), I try to pick the device, but, frankly I don't know what the problem is.
    Even leaving the DS18B20 module working, the situation is not better.

    It would be nice to know and deepen the root cause of the problem (otherwise, even by replacing the device, I would remain locked on the first sensor selection)
    Meanwhile I continue with the experiments ...

    Regards

  • Could you call getTime() a few times, and see if the value from it really does go up by 1 every second?

    I seem to recall ST changed the crystal halfway through manufacture of their F401Nucleo boards, so some run at a completely different speed to others! https://github.com/espruino/Espruino/iss­ues/457

    I imagine that could cause you some issues. I've used DS18B40 on the Espruino Wifi just a few days ago and it worked great, so it's not specifally a Espruino + STM32F4 issue.

  • Hi Gordon,
    many thanks for the support.
    The Nucleo board I'm using for this experiment is a C-03 board (from the discussion you have linked, it seems to be a "last generation" one)
    Here is the result of the same test described in the post you reported.
    The steps are:
    1) press the USER button and start stopwatch measure (60 sec)
    2) press the button again (when about 60 seconds are passed as indicated by the stopwatch)

     _____                 _
    |   __|___ ___ ___ _ _|_|___ ___
    |   __|_ -| . |  _| | | |   | . |
    |_____|___|  _|_| |___|_|_|_|___|
              |_| http://espruino.com
     1v93 Copyright 2016 G.Williams
    Espruino is Open Source. Our work is supported
    only by sales of official boards and donations:
    http://espruino.com/Donate
    >setWatch(function(e) {  console.log(getTime());
    :console.log(e.time - e.lastTime); }, BTN, { repeat:true, edge:'falling', debounce:10});
    =1
    1656.09075108333 // step 1)
    NaN
    1716.41545185714 // step 2)
    60.15261686904
    > 
    

    The difference between the two presses of the USER button is about 60 sec confirming a good accuracy of the internal timer / oscillator of the board.
    Let me know if the test is OK for you .

    Something strange happens when I pass from the device search (which returns the correct sensor serial) to the device selection on the 1-Wire line...
    Do you have any other suggestions?

    Thanks in advance.

    PS: I also have a Nucleo F401RE Board C0-2 (still working), I try to repeat the experiments with the latter (to see if there are differences)

  • Hi,
    please find here the results for my Nucleo F401RE C0-2;

    1) Clock accuracy:

     _____                 _
    |   __|___ ___ ___ _ _|_|___ ___
    |   __|_ -| . |  _| | | |   | . |
    |_____|___|  _|_| |___|_|_|_|___|
              |_| http://espruino.com
     1v93 Copyright 2016 G.Williams
    Espruino is Open Source. Our work is supported
    only by sales of official boards and donations:
    http://espruino.com/Donate
    >
    =undefined
    >displayResults()
    31.64555874999 10.21179736904
    41.81299369047 10.16743494047
    51.65689622619 9.84390253571
    61.63007591666 9.97317969047
    71.57576703571 9.94569111904
    81.62324639285 10.04747935714
    91.60931855952 9.98607216666
    101.71581107142 10.10649251190
    111.63114655952 9.91533548809
    121.65549364285 10.02434708333
    average of  11  x-second measurements:  0.91130428030
    =undefined
    >
    

    The average value of measurements is close to 10 s (the clock\Timer accuracy seems OK)

    2) DS18B20 "cabled sensor" issue
    Unfortunately I have the same result of previous board (please see below)...

     _____                 _
    |   __|___ ___ ___ _ _|_|___ ___
    |   __|_ -| . |  _| | | |   | . |
    |_____|___|  _|_| |___|_|_|_|___|
              |_| http://espruino.com
     1v93 Copyright 2016 G.Williams
    Espruino is Open Source. Our work is supported
    only by sales of official boards and donations:
    http://espruino.com/Donate
    >
    =undefined
    Temp is null°C
    Temp is null°C
    Temp is null°C
    Temp is null°C
    

    Regards

  • To be honest we're looking for wildly different timings - like a factor of two.

    I'm sorry, but i'm not sure what to suggest, unless you're willing to get a storage oscilloscope out and see what's happening on the wire itself?

    Does this work on other types of board running Espruino, or with other sensors? I know you said the current one works with other software, but it could be Espruino's timings are out of spec, and some devices work and some don't? Just a guess though.

  • Unfortunately I do not have another sensor (of the same type), nor the oscilloscope for electric measurements (sigh!).
    Anyway, I will try to get the latter because I don't want to leave the question open!

    However, I agree with your hypothesis, it may be a tolerance problem of the device \ sensor respect to the low-level timings applied by Espruino (if I understand well).

    This leads me to ask a question (for purely cognitive purposes) about how low level operations are organized in Espruino (e.g. for the oneWire interface).
    For example, how does a reset pulse is sent on the OneWire interface?
    Sorry if it's a trivial question maybe, but it's just for better know some details that could explain some difference with the working implementation on the same board...

    The OneWire Class and the DS18B20 sensor module correctly hide these "electrical" aspects and only expose functions to send and receive bytes, initialize the line, get the temperature value etc, etc, ...
    Thanks in advance for the feedback!

    Regards

  • Your best bet is to find the function in the reference: http://www.espruino.com/Reference

    Then there's a ⇒ symbol next to the function's title. Click on that and you go to the implementation: https://github.com/espruino/Espruino/blo­b/master/src/jswrap_onewire.c#L111

    If you want actual specifics of the OneWire protocol, it's best just to google it.

    Can you try adding this to the end of your code:

    sensor.getTemp = function(callback) {
      function read(me) {
        var s = me._r();
        var temp = s[0] + (s[1]<<8);
        if (temp & 32768) temp -= 65536;
        temp = temp / ((me.type==10)?2:16);
        if (callback) callback(temp);
        return temp;
      }
      this.bus.select(this.sCode);
      this.bus.write(0x44, true);
      if (!callback) return read(this);
      var tim = {9:94, 10:188, 11:375, 12:750};
      setTimeout(read, tim[this.getRes()], this);
    };
    

    And see what it says? It'll ignore the CRC.

  • One other option is that the sensor (or your wiring) doesn't have 3.3v connected. DS18B20 can work off just data+GND, but I'm not 100% sure the driver for it supports that.

    If your other code did support it, it'd still work. On Espruino it'd keep resetting, so the CRC would likely be wrong.

  • With the resistor between data and 3.3V, running just on ground and data, should not be a concern of the module... 'Properly' hardwired and capacitor / diode supported sensor should do just as fine... with resistor related and parasitic power supply capacitor - capacitor of sufficient capacity.

    @Gordon, if 3.3V is not properly supported, why would @Blizzard get a proper sensor serial # (w/ correct calculated checksum)?

    EDIT:

    [powering mode] ...should not be a concern of the module...

    I was wrong about this... module implementation matters: module has to apply 'strong pull up' within 10[us] for at least 10[ms] after sending Convert T [44h] or Copy Scratchpad [48h] command (with no other bus activity going on) to support at least 1.5[mA] current for the requested operation.

  • Hi Gordon, allObjects,
    many thanks again for the feedabck, as usual you are a "wealth of information".
    I try to start from the last suggestion (which gives me many cues for action) making the following simple experiment.

    The fairly simple connections are made through a breadboard; explicitly removing the cable on the power line connected with 3.3V pin on the Nucleo board I can still read the serial number via Espruino (this is for me quite surprising since I had the same idea of @allObjects concerning power supply management)
    Same behaviour for the other "native" implementation where I get the serial number correctly but, subsequently, the sensor always read 85 ° C from the scratchpad memory which, according to the device user manual, represents the value of the scratchpad at "power up state"
    No subsequent temperature variation is measured \ perceived by the sensor in this configuration.
    Reconnecting the power supply pin (even "on the fly") all goes back to working properly...
    Regards

  • Driver module implementation matters... see Edit: towards the bottom of my previous post.

    Unfortunately this is not helpful in explaining what is going on...

    It just seems to me that no measurement / conversion / scratchpad writing takes place after powering up. Verifying the connectivity on the sensor's power line to 3.3V should be checked.

    I would try implement some 'self-monitoring',... for example - you be the judge if it is 'totally out of mind':

    Apply the following changes to

    • the wiring: Place a 180R (180 Ohm Resistor) between 3.3V supply and power line of the sensor, and make a wire connection from power line of the sensor to a free 'sense' pin on your processor board.
    • the code: The 'sense' pin you configure as plain input (or - in a second round - with pulldown) as first in your code. As last in your code you put a setWatch on it with repeat on falling edge option and a function function() { console.log('watch fired'); }. Put all code except the sense pin initialization and first two lines from very first code post into a function which you call startMeasuring (or what ever name you like).

    Upload the code (from within the edit pane) and invoke the function from console by entering startMeasuring(). Doing so, you separate the upload and module load from actual run time (containing potential interference). You may go even a step further and separate the module load from the connect...

    pinMode(A1, "input");
    var ow = new OneWire(A0);
    var sensorMod = require("DS18B20");
    function startMeasuring() {
      var sensor = sensorMod.connect(ow);
      setInterval(function() {
        sensor.getTemp(function (temp) {
          console.log("Temp is "+temp+"°C"); 
        });
      }, 1000);
      setWatch(function(){ console.log('watch fired'); },
          A1, { repeat: true, edge:'falling', debounce:0 });
    }
    

    When the console shows 'watch fired', it is an indicator that power failed... due to a too weak supply... if not, you may weakening/increasingly limiting the supply by increasing the resistor in the powering path to 330R / 470R / 680R / 1K / 2.2K / 3.3K / 4.7k / ... At one point you should get the 'watch fired' message... caused by the sensor performing the power hungry convert / copy to scratch pad operation, tearing/pulling down the power line and getting not enough power anymore - especially when choosing the highest conversion resolution which takes about 3/4 of a second. The 180R in the powering path still allows 1.6[mA] and 3.0V for the sensor when supply - the 3.3V board pin - is 'exactly' 3.3V and able to provide 1.67[mA]. (Did you ever check this 3.3V board pin's properties/abilities/behavior?)

  • Thank you very much for your suggestion!
    For me it is correct to investigate in this direction (in the past I have never experienced any issue related to "poverty" of the power supply contacts).
    For information, using the "native" implementation and the same board \ connections, the temperature sensor also works at 5V without problems (even with Arduino the 5V is OK).
    With Espruino instead I get the same failure unfortunately:

    Temp is null°C
    Temp is null°C
    Temp is null°C
    

    I hope to give the first results as soon as possible ...
    Stay tuned!

    Regards

  • Hello all,
    unfortunately, the suggested procedure does not seem to give clues for now.
    I tried the configuration and the piece of code suggested by using different values of the resistors in my possession (200R, 470R, 680R, 1K, 4.7K, 10K) without triggering the "watch fired" message (the message appears iteratively, as expected, only by removing the resistor leaving the pin floating).
    The "sentinel pin" (A1) mode has been configured as:

    • input
    • input_pulldown

    Note that also the "native application" continues to work properly, even when connecting the resistor between the sensor power pin and 3.3V power line supplied by the module, except when the connected resistor is 10K.
    In this latter case, the converted temperature values are clearly incorrect (but return good immediately after the resistor is removed or replaced with a smaller one among those listed).
    This type of resistor values seems to undermine the sensor acquisition and conversion capability...

  • @Blizzard, thanks for going thru the procedures... it is really puzzling why the circuitry is not working... I checked for the processor types and see that they are different. Even though there is not an obvious explanation, I have to conclude that something is just not the same. In other words, something with the 1-wire driver is not working on this processor chip but it works on all the other Espruino boards...

    I hope it is not one of the ST libs used in the Espruino builds... but I would have to go for that...

  • In this latter case, the converted temperature values are clearly incorrect

    Did you ever try the code I posted above that doesn't check the CRC? It would imply that the 'native' code you have doesn't bother with it.

    I hope it is not one of the ST libs used in the Espruino builds... but I would have to go for that...

    It won't be - it works fine for me on official ST boards. Plus, I wrote the libs and they're used in all the different Espruino boards, so you'd expect there to be more problems reported across the board if they actually had issues.

  • Try a 2.2k or 3.3k resistor. Or 2 or 3 1k in series if that is all you have.

    What length cable are you running?

    On a raspberry pi I recall that 4.7k didnt work (also 3.3v) so I think it was 3.3 I used in the end.

  • Hello all,
    many thanks for the tips!
    @Gordon: I have not yet tried the code that ignores the CRC verification. But I'm going to try...
    Could you please clarify which "piece of code" I need to merge with the code you suggested?

    @Wilberforce: the DS18B20 sensor I'm using is cabled with 1 m cable.
    Since I don't want to leave anything not attempted, I will try the resistor values you suggest if the test suggested by Gordon is not OK ...

  • Hi @Gordon,
    maybe there is a misunderstanding because I did not explain it well.
    This is your code that ignores the CRC in recovering \ convert the temperature from the device.
    What is not 100% clear to me is what piece of "my code" should be merged with this one kindly suggested by you.
    Until now, I have used the "hello world" example that is shown in the DS18B20 sensor page (http://www.espruino.com/DS18B20)
    Alternatively, I have tried the OneWire code example to send raw commands to the device (retrieved from the relevant page: http://www.espruino.com/OneWire)

    Could you please clarify which of the two "pieces" should I use?

    Thanks in advance for your feedback...

  • You literally just insert it in-line and it'll overwrite the existing implementation:

    var ow = new OneWire(A1);
    var sensor = require("DS18B20").connect(ow);
    sensor.getTemp = function(callback) {
      function read(me) {
        var s = me._r();
        var temp = s[0] + (s[1]<<8);
        if (temp & 32768) temp -= 65536;
        temp = temp / ((me.type==10)?2:16);
        if (callback) callback(temp);
        return temp;
      }
      this.bus.select(this.sCode);
      this.bus.write(0x44, true);
      if (!callback) return read(this);
      var tim = {9:94, 10:188, 11:375, 12:750};
      setTimeout(read, tim[this.getRes()], this);
    };
    setInterval(function() {
      sensor.getTemp(function (temp) {
        console.log("Temp is "+temp+"°C"); 
      });
    }, 1000);
    
  • Thanks a lot for the complete code.
    Unfortunately I am not yet able to read the correct temperature (see below):

     _____                 _
    |   __|___ ___ ___ _ _|_|___ ___
    |   __|_ -| . |  _| | | |   | . |
    |_____|___|  _|_| |___|_|_|_|___|
              |_| http://espruino.com
     1v93 Copyright 2016 G.Williams
    Espruino is Open Source. Our work is supported
    only by sales of official boards and donations:
    http://espruino.com/Donate
    >
    =undefined
    Temp is -0.0625°C
    Temp is -0.0625°C
    Temp is -0.0625°C
    Temp is -0.0625°C
    Temp is -0.0625°C
    Temp is -0.0625°C
    Temp is -0.0625°C
    

    The device returns a negative temp value that seems compatible with a scratchpad reading like FF ... FF.
    Also changing the value of the pull up resistor between data and 3.3V (e.g. 3.3K or 2K) the result does not change (note: the "native code" also works fine without pull-up connected!)
    At this point, I try to focus on the low level differences between the two implementations (the one that works and Espruino).
    I see so far slight differences in the low-level commutation timings (e.g. in reset pulse, write bit "0" or "1"), though both implementations seem compatible with device sampling / response times.
    Maybe these differences combined with the fact that I'm using a sensor with only a 1m cable can determine the different behavior.
    Obviously to go deep I have to recover an oscilloscope that can help me in the analysis of the low level signals between the two cases (not immediately unfortunately).
    Any other suggestion from you is welcome!

  • I just had a similar situation with an ESP32 and 2 one wire devices using a breadboard.

    A search would show the codes:

      var ow = new OneWire(D23);
      var sensors = ow.search().map(function (device) {
        return require("DS18B20").connect(ow, device);
      });
    
    =[
      {
        "bus": OneWire { "pin": D23 },
        "sCode": "28cc2e230500006b",
        "type": 28 },
      {
        "bus": OneWire { "pin": D23 },
        "sCode": "283260dc04000001",
        "type": 28 }
     ]
    

    however - the reads failed. It turns out the pins were not seated properly - enough to get the ROM code, but not enough for a reading.

    var model = {
      temp: [50,50]
    };
    
    function readTemps() {
       sensors.forEach(function (sensor, index) {
        model.temp[index]=sensor.getTemp();
        console.log(model);
      });
    }
    
  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Problem with the DS18B20 temperature sensor (NUCLEO-F401RE board )

Posted by Avatar for Blizzard @Blizzard

Actions