Shop OBEX P1 Docs P2 Docs Learn Events
DS18B20 Sensors with sub-zero temperatures *edited thread title* — Parallax Forums

DS18B20 Sensors with sub-zero temperatures *edited thread title*

parts-man73parts-man73 Posts: 830
edited 2009-12-23 18:24 in Propeller 1
I was using the One wire object from the exchange to read temperatures from a DS18B20 sensor (which is compatible to a DS1822) for a project that I was working on for a friend (he needed to replace the thermostat in a walk-in freezer)

The object worked as expected, until the temperature reached below 32 degrees F ( below 0 in Celsius) The object had no way of dealing with sub-zero temps! The sensor can read temps in the range of -67 to 257 F (or -55 to 125 C)

I am in the process of rewriting the Object to return a temperature with an indication of it's sign, along with the ability of reading several One wire sensors on the same port (by reading the unique 64 bit serial # stored in the ROM of each sensor)

I have figured out how to check for negative, and how to convert the negative number to a returnable value

My question is.... How best to return this value?
  • Should it be returned as 2 values? the temperature, and a second boolean value for the sign?
  • a Float value?
  • add a fixed value to the number, which would have to be subtracted outside of the Object to get the correct temp

I could've just chosen how I wanted to do it for my project at hand and went with it, But I want to submit this to the OBEX when it's done, so I want to use an agreeable method.

And on that subject, what are the rules about uploading Objects that are modified/improved versions of someone else's Object? Step one ought to be to contact the original author, but how do I find out the name on the forums vs the real names listed in the OBEX ?

Thank you in advance!

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Brian

uController.com - home of SpinStudio - the modular Development system for the Propeller

PropNIC - Add ethernet ability to your Propeller! PropJoy - Plug in a joystick and play some games!

SD card Adapter - mass storage for the masses Audio/Video adapter add composite video and sound to your Proto Board

Post Edited (parts-man73) : 12/9/2008 7:41:37 PM GMT

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2008-12-08 05:30
    The DS18B20 returns a 16 bit value which is a fixed binary point signed value. It should be returned exactly as read from the DS18B20 only with the sign extended to 32 bits (using the ~~ prefix operator). At that point, it's a valid temperature in units of 1/16ths of a degree. If you want the temperature in degrees, just arithmetic shift right by 4 bits. If you want the temperature in half degrees, just arithmetic shift right by 3 bits. You can use the floating point package if you need it and convert the integer value to floating point and divide by 16 in floating point to get the right value.

    The 1-Wire object itself doesn't do anything specifically for the DS18B20. It just handles the 1-Wire Protocol. The routines in the Object Exchange archive that handle the DS18B20 or DS1822 are demo routines intended to illustrate the use of the lower level object and to be used as models for specific routines in your project. As such, I'm not sure you could call the sign issue a problem so much as that you needed some features not included in the sample or demo programs.

    There are two objects that handle 1-Wire, one of them partially in assembly and the other all in Spin. You can search the forum Member List for "camt" (Cam Thompson) and send a PM. Perhaps he'll modify the demo program to include a comment about how the sign could be extended to get a proper signed temperature in the returned 32 bit value.

    Post Edited (Mike Green) : 12/8/2008 5:45:41 AM GMT
  • ElectricAyeElectricAye Posts: 4,561
    edited 2008-12-08 06:06
    Oh nooooOOOOOooooo,

    I, too, am using the DS18B20 and was just getting ready to test it into temperatures below 32 F this week.
    So am I to understand that there is no known way to use the OBEX code for reading temperatures below 32 F ????.
    I need this thing to read down to -30 F.


    freaked.gif
  • ElectricAyeElectricAye Posts: 4,561
    edited 2008-12-08 15:30
    Okay,

    I'm not sure this really works, there doesn't seem to be any feedback on it, but I'm hoping this could be adapted for use by the Propeller in regards to these DS18B20s... because I'm in the same sinking boat as Parts-man at this point. Anybody know if this approach is as good as advertised?


    http://forums.parallax.com/showthread.php?p=694845

    thanks,
    Mark

    eyes.gif

    Post Edited (ElectricAye) : 12/8/2008 3:35:18 PM GMT
  • Mike GreenMike Green Posts: 23,101
    edited 2008-12-08 15:47
    ElectricAye,
    As I stated in my previous message, all you need to do is extend the sign of the 16 bit value returned from the DS18B20. You can use the Spin "~~" prefix operator for this. What you then have is an integer value in 1/16ths of a degree which you can use the arithmetic shift operator "~>" to get a value in other units (1/8ths, 1/4ths, 1/2 degrees, or whole degrees).

    Please read the datasheet for the device rather than just relying on the incomplete documentation that's part of the object. Most authors of Propeller objects assume that the user is looking for a library routine and examples of its use, not a tutorial on the object and the device. They expect that users will take the time and effort to locate and use readily available documentation (like device datasheets) and that they don't have to duplicate and explain it.
  • parts-man73parts-man73 Posts: 830
    edited 2008-12-08 15:52
    Mike, thank you for your response. I think i get it now. I was trying to make the object do the two-compliment conversion when it wasn't really necessary. what I really needed to work on was how my program handled the result. I wasn't aware of the "sign extended"

    I still plan to make a few additions to the object for multiple sensors on one drop.

    ElectricAye - don't worry, you can get negative temperatures out of it, follow Mike's advice, or ask to look at my code after I make necessary adjustments.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Brian

    uController.com - home of SpinStudio - the modular Development system for the Propeller

    PropNIC - Add ethernet ability to your Propeller! PropJoy - Plug in a joystick and play some games!

    SD card Adapter - mass storage for the masses Audio/Video adapter add composite video and sound to your Proto Board
  • ElectricAyeElectricAye Posts: 4,561
    edited 2008-12-08 16:11
    Mike, Parts-man,

    thanks, you guys. As usual, upon seeing this problem, I went into panic mode. And since I am dumb as a rock when it comes to bit shifting and One Wire stuff, and since I'm swamped with other issues right now, the idea of getting down and dirty with the nitty gritty of bits this week left me feeling shot in the head. I'm feeling bandaged now, so I'll try to find time to understand what Mike is saying. Partsman, pardon me, though, if I tap you on the shoulder later on and ask to see how you solved this problem.

    cheers,
    Mark


    blush.gif
  • Mike GreenMike Green Posts: 23,101
    edited 2008-12-08 16:23
    parts-man73,
    Do PM camt once you've cleaned up your changes. It's usually best for the original author to incorporate other people's ideas into their own work when it makes sense. It's a matter of style and consistency. If the original author isn't interested or not available, you can certainly post your modified version separately, but then you assume responsibility for possibly updating your modified version if the original author later makes changes or corrections.

    If you don't include the low level routines, but merely reference them and provide new examples of their use (like with multiple DS18B20s), then your object would be separate from the existing one. The Extended FullDuplexSerial object is an example of this. It provides additional functionality for FullDuplexSerial, but is only dependent on the functionality of FullDuplexSerial, not the actual internal code.

    Post Edited (Mike Green) : 12/8/2008 4:30:02 PM GMT
  • ElectricAyeElectricAye Posts: 4,561
    edited 2008-12-08 17:03
    Mike Green said...
    parts-man73,

    If you don't include the low level routines, but merely reference them and provide new examples of their use (like with multiple DS18B20s), then your object would be separate from the existing one.

    I thought the current object for the DS18B20 already allows up to 8 units on one wire. I know I've got 6 working right now and have never had a problem. Are we all talking about the same object for this?

    I think I'm using an object created by Micah Dowty, which I got from the Obex. obex.parallax.com/objects/342/

    Post Edited (ElectricAye) : 12/8/2008 5:09:49 PM GMT
  • parts-man73parts-man73 Posts: 830
    edited 2008-12-08 18:40
    We are using different objects.

    I am using the object written by Cam Thompson. My current project only involves 1 sensor, but as I was reading through the Datasheet, I saw references on how to support multiple sensors, and thought that would be a worthwhile addition. If there's another object that already achieves this, than I won't spend any time re-doing this.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Brian

    uController.com - home of SpinStudio - the modular Development system for the Propeller

    PropNIC - Add ethernet ability to your Propeller! PropJoy - Plug in a joystick and play some games!

    SD card Adapter - mass storage for the masses Audio/Video adapter add composite video and sound to your Proto Board
  • ElectricAyeElectricAye Posts: 4,561
    edited 2008-12-08 19:09
    Parts-man,

    Micah Dowty's one wire routine is written entirely in SPIN and has a built-in ability for DS18B20s. I know it can handle at least 6 DS18B20s but I don't know enough about the code to tell if it can handle below 32 degrees F. I'm not so proficient with SPIN or with One Wire technology to tell what exactly it is capable of doing. And I haven't actually tested my DS18B20s below 32 F.... yet. If you can tell by looking at Micah's code, please let us know. Or if you know how to fix it for use below 32 F, I would greatly appreciate knowing how you did it.

    thanks,
    Mark
  • Mike GreenMike Green Posts: 23,101
    edited 2008-12-09 00:03
    Mark,
    I've already described twice how to get the existing routines to handle negative temperatures. Please reread my previous postings.
  • ElectricAyeElectricAye Posts: 4,561
    edited 2008-12-09 03:32
    Hi Mike,

    thanks for giving insight into solving this problem. If I understood what I was doing, I'm sure your advice would make everything a snap. Problem is, I have yet to learn how any of this bit shifting and communication protocol works. Perhaps it's hard to believe, considering what I've got my one Propeller doing these days*, but I have yet to learn how any of the protocols for One Wire or i2c, etc. really work. Mind you, it's on my list of things to sit down and grok someday, but I'm dashing from one thing to another with my project, learning only what I need to learn at the moment to get a prototype up and running. It's certainly not a purist approach but I do make progress - of a sort. If I can find no other way out of my problem, then everything comes to a screeching halt while I sit down and start grokking how and why I need to shift bits around. Otherwise, I'm happy to stand on the shoulders of giants to get the job done. This is the kind of sad situation a Mech E (who deserved a D but was gifted with a C in his Intro to Electronics) finds himself in when tossing himself into the electronic jaws-infested waters. Which is what I've done. Don't ask me why. I must be out of my mind.

    thanks as always,
    Mark



    *RTC, SD card data recorder, six channels of simultaneous pulse counters, 6 channels of temperature, TV output, various switch controls, automatic comparator threshold control via digital pots, etc. smile.gif
  • parts-man73parts-man73 Posts: 830
    edited 2008-12-09 04:04
    Mark,

    Let me try to explain how I understand it.

    The temperature data that gets returned is 16 bits, or 2 bytes. The LSB and MSB are comprised of the following....

    MSB
    bit 15-bit 11 is the sign.... 5 0's if positive, 5 1's if negative.
    bit 10 is 26
    bit 9 is 25
    bit 8 is 24

    LSB
    bit 7 is 23
    bit 6 is 22
    bit 5 is 21
    bit 4 is 20
    bit 3 is 2-1
    bit 2 is 2-2
    bit 1 is 2-3
    bit 0 is 2-4


    In the object I'm using the statement of code constructs the word of data from the 2 bytes read.

    "tempC := ow.readByte + ow.readByte << 8 "

    since the << operator has a higher prescidence than +, that part of the equation is done first. The MSB is read and shifted left 8 bits, that is then added to the LSB, filling in the lower 8 bits.

    You now have a 16 bit number, everything in bit 4-10 is the whole part of the #
    everything in bits 0-3 is to the right of the decimal point.
    if you the shift everything to the right 4 bits, everything to the right of the decimal point is truncated.

    so if you have the data returned

    00000000 01010000

    shift to the right 4 bits you'll have 101 - or the whole number 5

    The above is for positive numbers.

    If the result is negative, the first 5 bits will be 1. and the data will be in two's compliment. (actually the positive number is also in two's compliment as well) for example....

    11111111 10111111

    to convert - first shift to the right 4
    11111111 11111011

    then invert all bits

    100

    and add 1, for the final result of 101, or 5 in decimal, only it's a negative 5

    The sign extending that Mike is speaking of extends this to a LONG data type by filling the upper 16 bits with the sign (all 0's for positive, all 1's for negative)

    And of course, the result is returned in degrees Celsius. You'll have to convert that to Fahrenheit if that's what you prefer.

    Hope this helps with your coding!

    If I'm wrong on any of this, please someone let me know.

    The only thing I'm confused about. Is when you shift right 4 bits, what is shifted in on the left? I assume 0's. so if I have a negative temperature, I need to take that into account.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Brian

    uController.com - home of SpinStudio - the modular Development system for the Propeller

    PropNIC - Add ethernet ability to your Propeller! PropJoy - Plug in a joystick and play some games!

    SD card Adapter - mass storage for the masses Audio/Video adapter add composite video and sound to your Proto Board

    Post Edited (parts-man73) : 12/9/2008 4:21:26 AM GMT
  • ElectricAyeElectricAye Posts: 4,561
    edited 2008-12-09 05:01
    Partsman,

    Wow! Thanks for posting all this information! You might have just motivated me to get off my keester and finally learn how this really works!


    smile.gif
  • Mike GreenMike Green Posts: 23,101
    edited 2008-12-09 05:29
    parts-man73/Brian,
    The arithmetic right shift operator "~>" does a right shift and, instead of putting zeroes in the bits on the left, copies the sign bit (bit 31) to those positions. As a result, it works like a signed divide by 2 (or power of 2). Try a few examples.
  • parts-man73parts-man73 Posts: 830
    edited 2008-12-09 13:07
    Mike,

    ah ha! that's why it wasn't working correctly! I was using the wrong shift operator.
  • ElectricAyeElectricAye Posts: 4,561
    edited 2008-12-09 18:36
    Alas,

    I just tested Micah Dowty's SpinOneWire-test for the DS18B20 and it confirmed that it does NOT show negative temperatures, either. Either that, or my ice formed at a balmy 7,377 degrees.

    Post Edited (ElectricAye) : 12/9/2008 8:24:32 PM GMT
  • ElectricAyeElectricAye Posts: 4,561
    edited 2008-12-09 20:17
    Hokay,


    Hey, Mike and Brian, thanks to you, I got it working (I think)



    For Micah Dowty's SpinOneWire-test all I needed to do was place temp:= ~~temp in the position shown below, which is about line 90 in the code





    ow.writeByte(ow#READ_SCRATCHPAD)
          temp := ow.readBits(16)
    
          temp := ~~temp  {Modified 9 Dec 2008.}
    
          ' Convert from fixed point to floating point
          degC := f.FDiv(f.FFloat(temp), 16.0)
          ' Convert celsius to fahrenheit
          degF := f.FAdd(f.FMul(degC, 1.8), 32.0)
    
    
    
    



    My block of ice now shows -12 degrees C.

    Thank you, Santa! roll.gif Mark

    Post Edited (ElectricAye) : 12/9/2008 10:11:32 PM GMT
  • Brian CarpenterBrian Carpenter Posts: 728
    edited 2008-12-27 21:05
    Mark

    can you show me a schematic of how to connect the ds18b20?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


    It's Only A Stupid Question If You Have Not Googled It First!!
  • parts-man73parts-man73 Posts: 830
    edited 2008-12-28 00:57
    See attached picture snipped from the datasheet - Vpu AND Vdd is are both 3.3V

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Brian

    uController.com - home of SpinStudio - the modular Development system for the Propeller

    PropNIC - Add ethernet ability to your Propeller! PropJoy - Plug in a joystick and play some games!

    SD card Adapter - mass storage for the masses Audio/Video adapter add composite video and sound to your Proto Board
    1174 x 286 - 46K
  • ElectricAyeElectricAye Posts: 4,561
    edited 2008-12-28 02:24
    Brian Carpenter,

    the schematic that parts-man73 posted is the same one that I have used. This is from the data sheet and is the "external power" option (as opposed to the parasitic power option). To attach more DS18B20's to this, you simply need to hook up the data pins to the "one wire data bus" and provide power and ground to each DS18B20. I've had six running at the same time one one data line without problems. I found out the hard way that the DS18B20 will operate even when its leads are submerged in tap water. I'm very happy with the way they work.

    I haven't tried the parasitic power mode, so I can't help you there.

    Hope that helps.

    Mark


    smile.gif
  • AquaaddictAquaaddict Posts: 20
    edited 2009-12-23 11:00
    I had the same problems with the negative readings, this forum and your help is very much appreciated!!!

    Thanks,

    Ants
  • BeanBean Posts: 8,129
    edited 2009-12-23 12:51
    I have a program in PropBASIC that uses the DS18B20, and here is what I did.

    ' Reads the temperature from a Dallas DS18B20
    ' Converts it to ascii and sends it to the PC
    ' Connect DS18B20 DQ pin to PIN 0 on the propeller
    ' Don't forget the 4.7K pullup resistor too...
    '
    DEVICE P8X32A, XTAL1, PLL16X
    FREQ 80_000_000
    
    Baud     CON "T115200"
    
    DQPin    PIN 0 INPUT   ' 1-Wire communication pin
    TX       PIN 30 HIGH   ' Send data back to PC
    
     
    temp     VAR LONG
    tempLSB  VAR LONG     ' Temperature LSB
    tempMSB  VAR LONG     ' Temperature MSB
    value    VAR LONG     ' Temperature
    ascii    VAR LONG(10) ' Conversion to ASCII
    
     
    ' Start of main code
    
     
    PROGRAM Start
     
    Start:
      ' Main code loop
      DO
        ' Perform a temperature conversion
        OWRESET DQPin
        OWWRITE DQPin, $CC  ' SkipROM
        OWWRITE DQPin, $44  ' Convert
        PAUSE 750           ' Wait for conversion
     
        ' Read temperature value
        OWRESET DQPin
        OWWRITE DQPin, $CC  ' SkipROM
        OWWRITE DQPin, $BE  ' Read Scratch
        OWREAD DQPin, tempLSB
        OWREAD DQPin, tempMSB
        value = tempMSB << 8  ' * 256
        value = value + tempLSB
     
        ' Check for negative temperature
        IF value > 4095 THEN
          value = $1_0000 - value
        ENDIF
     
        ' Convert value to ascii
        temp = value >> 4      ' Get whole value
        STR ascii, temp, 4, 3  ' 3=Signed leading spaces
    
        ascii(4) = "."
    
        temp = value AND 15    ' Get fractional value
        temp = temp *  625 ' 10000 / 16
        STR ascii(5), temp, 4, 0 ' 0=Unsigned leading zeros
    
        ascii(9) = 13 ' Carriage return
     
        ' Output temperature to PC
        FOR temp = 0 TO 9
          SEROUT TX, Baud, ascii(temp)
        NEXT
    
      LOOP
    END
    
     
     
    


    Bean

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    PropBASIC home page www.propbasic.com


    Post Edited (Bean (Hitt Consulting)) : 12/23/2009 5:35:59 PM GMT
  • JonnyMacJonnyMac Posts: 9,208
    edited 2018-08-08 23:48
    I wrote my own 1-wire cog (PASM) and provided a demo that shows you how to deal with any returned temperature within its range at the resolution you select (can be changed for some devices).
Sign In or Register to comment.