With sudo modprobe w1-gpio, w1-therm, the issue is that the "w1_slave" file doesn't report the correct temperature for below zero temperatures in the "t=..." entry, see http://bjohas.de/Blog/20141113_measurin ... th_DS18B20
for details. (You can use the hexadecimal values to get the temperature if you want, that's correct, but the value in decimal is not correct.)
Any thoughts as to why this is, and how it can be fixed?
- DougieLawson
- Posts: 42176
- Joined: Sun Jun 16, 2013 11:19 pm
- Location: A small cave in deepest darkest Basingstoke, UK
Re: Measuring below zero temperatures with DS18B20
Can you post your code?
I did a whole bunch of stuff with the data from a DS1624 to get the sign bit correct.
http://www.raspberrypi.org/forums/viewt ... 02#p625402
I did a whole bunch of stuff with the data from a DS1624 to get the sign bit correct.
http://www.raspberrypi.org/forums/viewt ... 02#p625402
Languages using left-hand whitespace for syntax are ridiculous
DMs sent on https://twitter.com/DougieLawson or LinkedIn will be answered next month.
Fake doctors - are all on my foes list.
The use of crystal balls and mind reading is prohibited.
DMs sent on https://twitter.com/DougieLawson or LinkedIn will be answered next month.
Fake doctors - are all on my foes list.
The use of crystal balls and mind reading is prohibited.
-
- Posts: 4002
- Joined: Thu Dec 27, 2012 4:05 am
- Location: Québec, Canada
Re: Measuring below zero temperatures with DS18B20
I'm using the ds18b20 to control a under water heater on my pond in the winter and never had problem.

Daniel

Daniel
Re: Measuring below zero temperatures with DS18B20
Hi both,
Dougie, I'll post some code in the next day or so. I'm away at a workshop, with limited connectivity.
Dan: With the pond temperature, did you read the temperature in hexadecimal, or in decimal from the t=.... entry? And did you use w1_slave? The error certainly is not with the sensor itself, and with w1_slave, the hex is fine too, but the t=.... isn't for me. (And some others online.)
Thanks for your comments!
Bjoern
Dougie, I'll post some code in the next day or so. I'm away at a workshop, with limited connectivity.
Dan: With the pond temperature, did you read the temperature in hexadecimal, or in decimal from the t=.... entry? And did you use w1_slave? The error certainly is not with the sensor itself, and with w1_slave, the hex is fine too, but the t=.... isn't for me. (And some others online.)
Thanks for your comments!
Bjoern
Re: Measuring below zero temperatures with DS18B20
I have been using the DS18B20 for over a year now measuring the outdoor and attic temps that can go below 0 degrees Celcius, without problems. I believe the "t=result" to be correct. Can you be more specific about what it is that's wrong?
-
- Posts: 4002
- Joined: Thu Dec 27, 2012 4:05 am
- Location: Québec, Canada
Re: Measuring below zero temperatures with DS18B20
This is my python code to read a specific DS18B20
Code: Select all
def LireDS18B20( CapteurId):
if CapteurId == None:
return None
Compteur=0
while(1):
try:
print(CapteurId,end=" : ")
fichier = open( "/sys/bus/w1/devices/" + CapteurId + "/w1_slave")
texte = fichier.read()
fichier.close()
ligne1 = texte.split("\n")[0]
crc = ligne1.split("crc=")[1]
if crc.find("YES")>=0:
break;
except IOError:
sys.stderr.write("Ne peut lire capteur {}".format(CapteurId))
#ok une erreur, bouclons
pass
Compteur = Compteur + 1
if Compteur >= 5 :
sys.stderr.write("5 erreur de sur capteur {} return None".format(CapteurId))
return None
time.sleep(1)
#ok nous avons une température valide
ligne2 = texte.split("\n")[1]
texte_temp = ligne2.split("=")
return float(texte_temp[1])/1000.0
Re: Measuring below zero temperatures with DS18B20
Daniel's code is not any different from the many examples out on the internet, and mine looks very much the same too.
Here is my simplified version:
Bjoern2, you may want to have a look at your code to see if there is a difference there. Otherwise, the real question is why you (or anybody else) think the negative temperatures as reported in the t=XXXX section are no good, or different from the value calculated from first two returned hex bytes?
Do you have examples so we can pin-point the problem?
Paul
Here is my simplified version:
Code: Select all
def get_sensor_data(ds, x=1):
'''
Function to get temperatures from one of the DS18B20 sensors.
The W1 interface is using GPIO-4 on pin 7.
First make sure we can read the sensor date by checking the access to the file.
Then we test for a proper CRC from the DS18B20, there must be a YES in the result.
We average the inside sensor readings a few times to get a stable return.
We also make sure we have no bogus readings.
If we get an exception, we use the previous reading so we can continue.
'''
try:
temp = 0
i = 0
avg_tmp = 0.0
while (i < x):
try:
with open(ds, "r") as fin:
text = fin.read()
except Exception as e:
print("error", "DS open data file failed: " + str(ds) + str(e))
return
if re.search ("YES", text):
# there is a valid crc in the recording
# strip the rubbish to get to the actual temperature reading
temperature_data = text.split()[-1]
temp = float(temperature_data[2:])
temp = (temp / 1000)
#
# we seem to have good results
#
avg_tmp = avg_tmp + temp
i += 1
else:
print("error", "Bad crc from sensor")
# continue the loop but skip the bad readings
# A little time to get a stable avg temp
sleep(2)
temp = round(avg_tmp/i, 1) # average and round the result to 1 decimal digit
return(temp)
except Exception as e:
print "exception : ", e
Do you have examples so we can pin-point the problem?
Paul
-
- Posts: 4002
- Joined: Thu Dec 27, 2012 4:05 am
- Location: Québec, Canada
Re: Measuring below zero temperatures with DS18B20
Ok I did look at the blog and it is really wrong.
First the data in the register map of the DS18B20 is in 16 bit short format. I don't know why is using bit 11 to tell it's a negative number.
The LSB (low byte of the temperature data is the first one).
The MSB is at the second position;
So to prove the point I use my Raspberry Pi with my small multi-IO module. Both will have the DS18B20 connect to it and we will check the temperature they Report.
From the Raspberry PI I got
i@WebIO /sys/bus/w1/devices/28-000004575f0a $ cat w1_slave
92 ff ff ff 7f ff 0e 10 78 : crc=78 YES
92 ff ff ff 7f ff 0e 10 78 t=-6875
it is reporting -6875 = -6.875 Celsius
The Hexadecimal value is 0xFF92 => 65426 unsigned short
To convert the data in signed short we could do this way
is bigger than 32767 if yes => New value = (value - 65536), if no => new value = value;
Than 0xff92 = ( 65426 - 65536) = -100 and if we divide it by 16 we got -6.875 celsius
Now my multi IO module report about the same thing with 1/16 of degree hotter.
The readSensor function return at the second value the unsigned short value . (65427).
Then the 1Wire driver for the Raspberry Pi display the correct result.
Daniel
First the data in the register map of the DS18B20 is in 16 bit short format. I don't know why is using bit 11 to tell it's a negative number.
The LSB (low byte of the temperature data is the first one).
The MSB is at the second position;
So to prove the point I use my Raspberry Pi with my small multi-IO module. Both will have the DS18B20 connect to it and we will check the temperature they Report.

From the Raspberry PI I got
i@WebIO /sys/bus/w1/devices/28-000004575f0a $ cat w1_slave
92 ff ff ff 7f ff 0e 10 78 : crc=78 YES
92 ff ff ff 7f ff 0e 10 78 t=-6875
it is reporting -6875 = -6.875 Celsius
The Hexadecimal value is 0xFF92 => 65426 unsigned short
To convert the data in signed short we could do this way
is bigger than 32767 if yes => New value = (value - 65536), if no => new value = value;
Than 0xff92 = ( 65426 - 65536) = -100 and if we divide it by 16 we got -6.875 celsius
Now my multi IO module report about the same thing with 1/16 of degree hotter.
Code: Select all
pi@WebIO ~/PIC_MULTI_10_IO $ python
Python 2.7.3 (default, Mar 18 2014, 05:13:23)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import PicModule
>>> remote11 = PicModule.PicMbus(11,57600,'/dev/ttyUSB0')
>>> remote11.readDS18B20(0)
-6.8125
>>> remote11.readSensor(0)
[1, 65427, 127]
Then the 1Wire driver for the Raspberry Pi display the correct result.
Daniel
Re: Measuring below zero temperatures with DS18B20
Hmm, that is an interesting observation Daniel.
However, it does not quite follow my own.
Here is what I do to follow the specification of the DS18B20 and to verify the results: I can't get a below zero degrees C at the moment, it's too warm here, and I can't put my rig into the freezer at the moment, this is as low as I could get it. Not that it matters much though.
So, the t=3937 or 3.937 degrees Celcius.
We need to verify that result against the Hex output of 0x3F00.
BTW, my Alarm Bytes (TH and TL) are always 0x4B 46 while your's are 0xFF FF. I can't explain that at the moment.
In any case the two byte value of 0x3F 00 are made up as follows (following the specification) Byte1 and Byte2 need to be reversed, so 0x3F 00 must be read as 0x00 3F
S are the sign bits, either 0 for positive or 1 for negative results
b6 through b0 are the positive portion of the temperature. b6 means 2^6
b-1 through b-4 are the negative portion. b-1 means 2^-1
Following this, the sign bits are SSSS S = 0000 0, which means we have a temperature above 0 degrees Celcius.
The positive portion of the temperature is in bits 000 0011, which is 3d.
The negative portion is 1111 or 1*2^-1 + 1*2^-2 + 1*2^-3 and 1*2^-4 = 0.9375
so the temperature derived from the Hex bytes is 3.9375 and the same as the t=3.937.
I would really like to see an example where the Hex data coming from the DS device through the W1 drivers is different from the t= value.
I hope this helps,
Paul
However, it does not quite follow my own.
Here is what I do to follow the specification of the DS18B20 and to verify the results:
Code: Select all
pi@TestRig ~ $ cat /sys/bus/w1/devices/28-000004da2313/w1_slave
3f 00 4b 46 7f ff 01 10 47 : crc=47 YES
3f 00 4b 46 7f ff 01 10 47 t=3937
So, the t=3937 or 3.937 degrees Celcius.
We need to verify that result against the Hex output of 0x3F00.
BTW, my Alarm Bytes (TH and TL) are always 0x4B 46 while your's are 0xFF FF. I can't explain that at the moment.
In any case the two byte value of 0x3F 00 are made up as follows (following the specification)
Code: Select all
Byte2 Byte1
Nibble1 Nibble2 Nibble3 Nibble4
S S S S S b6 b5 b4 b3 b2 b1 b0 b-1 b-2 b-3 b-4
S are the sign bits, either 0 for positive or 1 for negative results
b6 through b0 are the positive portion of the temperature. b6 means 2^6
b-1 through b-4 are the negative portion. b-1 means 2^-1
Following this, the sign bits are SSSS S = 0000 0, which means we have a temperature above 0 degrees Celcius.
The positive portion of the temperature is in bits 000 0011, which is 3d.
The negative portion is 1111 or 1*2^-1 + 1*2^-2 + 1*2^-3 and 1*2^-4 = 0.9375
so the temperature derived from the Hex bytes is 3.9375 and the same as the t=3.937.
I would really like to see an example where the Hex data coming from the DS device through the W1 drivers is different from the t= value.
I hope this helps,
Paul
-
- Posts: 4002
- Joined: Thu Dec 27, 2012 4:05 am
- Location: Québec, Canada
Re: Measuring below zero temperatures with DS18B20
No not against 0x3F00 but 0x003F
LSB first
0x003F => 63 => 63/16 = 3.9375 Celsius
Don't mixt little endian and big endian Format.
Daniel
LSB first
0x003F => 63 => 63/16 = 3.9375 Celsius
Don't mixt little endian and big endian Format.
Daniel
Re: Measuring below zero temperatures with DS18B20
Hi Daniel,
You are absolutely right, of course, but note that for the sake of others reading this post, I was following the specification in the datasheet where it lists the individual bits and bytes. Because this will make it easier to track an error somewhere.
Of course, the calculation to get at the proper value is indeed using Little Endian notation (swapping byte 0 and 1), and divide that by 16 as you pointed out. But that makes it difficult to find a stuck bit, a poor conversion in the driver or a bad transmission stream from the DS to the Pi. (regardless of the CRC) Which was the reason for this post.
BTW, not that it matters, but because the W1 drivers program the DS to use 12 bit precision in the Configuration Register, (both our DS's report 0x7F), I use the 12th bit to test for negative numbers. With 0x7F, Bit R1=1 R0=1; DS is set to 12 bit resolution and then has a 750 mSec conversion time.
I hope this helps, all we need now are some "bad" samples.
Paul
You are absolutely right, of course, but note that for the sake of others reading this post, I was following the specification in the datasheet where it lists the individual bits and bytes. Because this will make it easier to track an error somewhere.
Of course, the calculation to get at the proper value is indeed using Little Endian notation (swapping byte 0 and 1), and divide that by 16 as you pointed out. But that makes it difficult to find a stuck bit, a poor conversion in the driver or a bad transmission stream from the DS to the Pi. (regardless of the CRC) Which was the reason for this post.
BTW, not that it matters, but because the W1 drivers program the DS to use 12 bit precision in the Configuration Register, (both our DS's report 0x7F), I use the 12th bit to test for negative numbers. With 0x7F, Bit R1=1 R0=1; DS is set to 12 bit resolution and then has a 750 mSec conversion time.
I hope this helps, all we need now are some "bad" samples.
Paul
-
- Posts: 4002
- Joined: Thu Dec 27, 2012 4:05 am
- Location: Québec, Canada
Re: Measuring below zero temperatures with DS18B20
Sometime it is good to figure out why a sensor, according to the data sheet shift more than one bit to output a negative number.
A lot of times we have to thing why and the answer is always obvious. The Sensor act this way because it has to behave properly to simplify the way a normal cpu will use the data.
Here it is the signed short value. A short is mostly 16 bits and the bit 15 indicates the sign. The way the calculator add signed number is the same has unsigned number. You only have to check the bit 15 and do a second complement calculation to display the negative value.
0xffff is 65535 in unsigned short but it is -1 in signed value.
The complement of 0xffff is 0 . The second complement means that you add 1 after the complement calculation and it gives 1.
Since bit 15 is 1 you add the sign '-' in front. Et Voila! If the Bit15 is zero you do nothing.
I made a small Excel spreadsheet to explain how it works. I do have excel 2011 for mac and the BITXOR is not implemented so I convert everything in text to do the work
Have a look.
https://dl.dropboxusercontent.com/u/488 ... lator.xlsx
Daniel
A lot of times we have to thing why and the answer is always obvious. The Sensor act this way because it has to behave properly to simplify the way a normal cpu will use the data.
Here it is the signed short value. A short is mostly 16 bits and the bit 15 indicates the sign. The way the calculator add signed number is the same has unsigned number. You only have to check the bit 15 and do a second complement calculation to display the negative value.
0xffff is 65535 in unsigned short but it is -1 in signed value.
The complement of 0xffff is 0 . The second complement means that you add 1 after the complement calculation and it gives 1.
Since bit 15 is 1 you add the sign '-' in front. Et Voila! If the Bit15 is zero you do nothing.
I made a small Excel spreadsheet to explain how it works. I do have excel 2011 for mac and the BITXOR is not implemented so I convert everything in text to do the work
Have a look.
https://dl.dropboxusercontent.com/u/488 ... lator.xlsx
Daniel
-
- Posts: 4002
- Joined: Thu Dec 27, 2012 4:05 am
- Location: Québec, Canada
Re: Measuring below zero temperatures with DS18B20
oops just corrected the spreadsheet about the sign bit.
It was on LSB and should have been on the MSB but the calculation was ok.
Daniel
It was on LSB and should have been on the MSB but the calculation was ok.
Daniel