#### Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

# Code example in One-Wire library for DS18b20 to display temperature less than zero

I have make an outdoor thermometer using the DS18b20. I used the one-wire library device code example for a single device and it has been working good. As the outdoor temperature has gone down this winter I have noticed a problem with the data the device code is sending. The temperature reading is good until it goes down past zero C. I have found some code on a different site that looks to address this problem, but it is code for the arduino. I am having a hard time rewriting the code so it will work with the existing library code.
You can see in the photo below the output I get when the temperature does down past zero. The MSB jumps to 255 and the LSB jumps to 255 just past zero c. As the temperature goes lower the LSB starts to decrease.
I am a newbie when it comes to coding and math was not a strong subject for me in school. If anyone could help me with the code change to the example I would very much appreciate it.
Bill

• You need to "sign extend" this to a 32 bit value. The value is two's complement encoded as a 16 bit signed value when you read it from the chip.

The easy way to do this in squirrel, as integers are signed, is to shift the value up towards the top of the 32 bit signed integer, then back down again. This will fill in "FFFF" at the top, and make everything magically work.

ie:

`local raw = (tempMSB << 8) + tempLSB;local temperature = ((raw << 16) >> 16)*0.0625;server.log("Temperature is "+temperature+"degC");`
• So integers are signed in squirrel, didn't know that. So much to learn. Thanks
• I ended up with below for my device code. It works.

`// Thermometer electric imp - DS18B20 function onewireReset() { // Configure UART for 1-Wire RESET timing ow.configure(9600, 8, PARITY_NONE, 1, NO_CTSRTS); ow.write(0xF0); ow.flush(); local read = ow.read(); if (read == -1) { // No UART data at all server.log("No circuit connected to UART."); return false; } else if (read == 0xF0) { // UART RX will read TX if there's no device connected server.log("No 1-Wire devices are present."); return false; } else { // Switch UART to 1-Wire data speed timing ow.configure(115200, 8, PARITY_NONE, 1, NO_CTSRTS); return true; }} function onewireWriteByte(byte) { for (local i = 0 ; i < 8 ; i++, byte = byte >> 1) { // Run through the bits in the byte, extracting the // LSB (bit 0) and sending it to the bus onewireBit(byte & 0x01); }} function onewireReadByte() { local byte = 0; for (local i = 0 ; i < 8 ; i++) { // Build up byte bit by bit, LSB first byte = (byte >> 1) + 0x80 * onewireBit(1); } return byte;} function onewireBit(bit) { bit = bit ? 0xFF : 0x00; ow.write(bit); ow.flush(); local returnVal = ow.read() == 0xFF ? 1 : 0; return returnVal;} // Wake up every 15 minutes and write to the server function awakeAndGetTemp() { local tempLSB = 0; local tempMSB = 0; // Run loop again in 15 minutes imp.wakeup(900.0, awakeAndGetTemp); if (onewireReset()) { onewireWriteByte(0xCC); onewireWriteByte(0x44); // Wait for at least 750ms for data to be collated imp.sleep(0.8); // Get the data onewireReset(); onewireWriteByte(0xCC); onewireWriteByte(0xBE); tempLSB = onewireReadByte(); tempMSB = onewireReadByte(); // Reset bus to stop sensor sending unwanted data onewireReset(); // Log the Celsius temperature local raw = (tempMSB << 8) + tempLSB; local temperature = ((raw << 16) >> 16)*0.0625; local tempFahrenheit = (temperature * 9 / 5 + 32) server.log(format("Temperature is : %3.2f Degrees F "tempFahrenheit)); }} // PROGRAM STARTS HEREow <- hardware.uart12;awakeAndGetTemp();`
• Glad it's working, and thanks for posting your code - I'm sure it'll help others!
• And I've updated the sample code in the 1-Wire Developer Guide
• It made me feel good that I was able to write some code again. The last time was when I was in a college class. IBM System/360, I may have a stack of punch cards up in the attic. :)