Can anyone tell me how to interpret negative temperature numbers returned from a DS18B20 in rooms.pde ?
OK 1 146 3 (below zero)
OK 1 236 3 (even more below zero)
Above numbers came in from a FROZEN DS18B20, numbers above zero are ok.
This forum has moved to forum.jeelabs.net - this read-only archive is for reference only!
Can anyone tell me how to interpret negative temperature numbers returned from a DS18B20 in rooms.pde ?
OK 1 146 3 (below zero)
OK 1 236 3 (even more below zero)
Above numbers came in from a FROZEN DS18B20, numbers above zero are ok.
problem solved (by reading datasheet ...)
Ah, good one. It's passed back as 10-bit value in tenths of degrees, and it's little-endian. If the second byte is 2 or 3, it's negative. That means the first byte is then in 2's complement. So my guess would be that "146 3" is -11.0°C (256-146) and "236 3" is -2.0°C (256-236) - doesn't match your note that the 2nd result is even more below zero, but that's what I get...
So to get the full range, do as follows: calculate the 10-bit value as "T = byte 1 + 256 byte2". If T is 512 or more, turn it into a negative value using "T = 1024 - T".
Does that produce correct results for you?
Hi JC,
Yes this is what I found out, thanks anyway !
Hi,
I am using this:
struct {
int temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
byte lobat :1;
} payload;
payload.temp0 = 23.50 100;
payload.temp1 = 23.50 100;
payload.temp2 = 23.50 100;
payload.temp3 = 23.50 100;
payload.temp4 = 23.50 100;
payload.temp5 = -5 100;
payload.temp6 = -5;
payload.temp7 = -11;
payload.lobat = rf12lowbat();
The result:
OK 34 46 9 46 9 46 9 46 9 46 9 12 254 251 255 245 255 0
How to calculate negative values?
> How to calculate negative values?
The geeky answer: flip the high bit, subtract 128, i.e.
int v = lo + 256 ((hi ^ 0x80) - 128);
or
int v = ((lo + 256 hi) ^ 0x8000) - 32768;
This sort of trickery is sometimes needed, to sign-extend 10-bit values etc.
For 16-bit values as in your example, it's much simpler to use C itself:
int v = (short) (lo + 256 hi);
Since ATmega's are little-endian, the low byte comes first.
Ooh, I've learnt a new C word (that sounds a bit wrong) :-)
(short)
Although my geeky mind will still prefer:
int v=((lo+256hi)^0x8000)-0x8000;
..because, to me at least, it's more obvious what it does!
Now having recently bought a couple of DS18B20+ (after a discussion about reading temperature in another post), I'm off to check my code because I suspect my temperature monitoring might be about to go a bit wrong when we get the first cold night!
slaps self for not testing properly
It works! Thanks!