DS18B20 Sensors with sub-zero temperatures *edited thread title*
parts-man73
Posts: 830
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?
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
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
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
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.
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
Post Edited (ElectricAye) : 12/8/2008 3:35:18 PM GMT
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.
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
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
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
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
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
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
I've already described twice how to get the existing routines to handle negative temperatures. Please reread my previous postings.
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.
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
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!
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.
ah ha! that's why it wasn't working correctly! I was using the wrong shift operator.
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
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
My block of ice now shows -12 degrees C.
Thank you, Santa! Mark
Post Edited (ElectricAye) : 12/9/2008 10:11:32 PM GMT
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!!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
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
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
Thanks,
Ants
Bean
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropBASIC home page www.propbasic.com
Post Edited (Bean (Hitt Consulting)) : 12/23/2009 5:35:59 PM GMT