Go Down

Topic: DS18B20 Temperature Code (Read 13007 times) previous topic - next topic

bellais

I'm new to Arduino and physical computing. I'm trying to read a temperature using the Dallas 18B20 sensor.  I'm using the following code that I found on this forum:

Code: [Select]

#include <OneWire.h>

/* DS18S20 Temperature chip i/o

*/

OneWire  ds(10);  // on pin 10

void setup(void) {
 // initialize inputs/outputs
 // start serial port
 Serial.begin(9600);
}



void loop(void) {
 byte i;
 byte present = 0;
 byte data[12];
 byte addr[8];
 
 if ( !ds.search(addr)) {
     //Serial.print("No more addresses.\n");
     ds.reset_search();
     return;
 }
 
 Serial.print("R=");  //R=28 Not sure what this is
 for( i = 0; i < 8; i++) {
   Serial.print(addr[i], HEX);
   Serial.print(" ");
 }

 if ( OneWire::crc8( addr, 7) != addr[7]) {
     Serial.print("CRC is not valid!\n");
     return;
 }
 
 if ( addr[0] != 0x28) {
     Serial.print("Device is not a DS18S20 family device.\n");
     return;
 }

 ds.reset();
 ds.select(addr);
 ds.write(0x44,1);         // start conversion, with parasite power on at the end
 
 delay(1000);     // maybe 750ms is enough, maybe not
 // we might do a ds.depower() here, but the reset will take care of it.
 
 present = ds.reset();
 ds.select(addr);    
 ds.write(0xBE);         // Read Scratchpad

 Serial.print("P=");  
 Serial.print(present,HEX);
 Serial.print(" ");
 for ( i = 0; i < 9; i++) {           // we need 9 bytes
   data[i] = ds.read();
   Serial.print(data[i], HEX);
   Serial.print(" ");
 }

 Serial.print(" CRC=");
 Serial.print( OneWire::crc8( data, 8), HEX);
 Serial.println();
}

This is the output:

R=28 16 F7 7D 1 0 0 9E P=1 8F 1 4B 46 7F FF 1 10 14  CRC=14
R=28 16 F7 7D 1 0 0 9E P=1 90 1 4B 46 7F FF 10 10 92  CRC=92
R=28 16 F7 7D 1 0 0 9E P=1 90 1 4B 46 7F FF 10 10 92  CRC=92

...

I'm sure this is exactly what it's supposed to output but how in the heck do I convert this output to a real temperature in either celsius or fahrenheit? Thanks.

Andrew

#1
Apr 15, 2008, 02:47 pm Last Edit: Apr 15, 2008, 02:50 pm by Andrew Reason: 1
Quote
I'm new to Arduino and physical computing. I'm trying to read a temperature using the Dallas 18B20 sensor.  I'm using the following code that I found on this forum:

This is the output:

R=28 16 F7 7D 1 0 0 9E P=1 8F 1 4B 46 7F FF 1 10 14  CRC=14
R=28 16 F7 7D 1 0 0 9E P=1 90 1 4B 46 7F FF 10 10 92  CRC=92
R=28 16 F7 7D 1 0 0 9E P=1 90 1 4B 46 7F FF 10 10 92  CRC=92

...

I'm sure this is exactly what it's supposed to output but how in the heck do I convert this output to a real temperature in either celsius or fahrenheit? Thanks.


There's a datasheet here: http://pdfserv.maxim-ic.com/en/ds/DS18B20.pdf which tells you how to decode the 9 bytes (8F 1 4B etc.) coming back from the device. At a quick glance the first two bytes encode the temperature. Page 4 in the PDF gives you the gory details:

Quote

The DS18B20 output temperature data is calibrated in degrees centigrade; for Fahrenheit applications, a
lookup table or conversion routine must be used. The temperature data is stored as a 16-bit sign-extended
two's complement number in the temperature register (see Figure 2). The sign bits (S) indicate if the
temperature is positive or negative: for positive numbers S = 0 and for negative numbers S = 1. If the
DS18B20 is configured for 12-bit resolution, all bits in the temperature register will contain valid data.
For 11-bit resolution, bit 0 is undefined. For 10-bit resolution, bits 1 and 0 are undefined, and for 9-bit
resolution bits 2, 1 and 0 are undefined. Table 2 gives examples of digital output data and the
corresponding temperature reading for 12-bit resolution conversions.
...


Andrew

dnear1

#2
Jun 08, 2008, 11:18 pm Last Edit: Jun 08, 2008, 11:20 pm by dnear1 Reason: 1
I modified the above code to provide Fahrenheit output.  it is easy to switch to celcius just comment out the appropriate line of code
Code: [Select]
#include <OneWire.h>

/* DS18S20 Temperature chip i/o

*/

OneWire  ds(10);  // on pin 10

void setup(void) {
 // initialize inputs/outputs
 // start serial port
 Serial.begin(9600);
}



void loop(void) {
 byte i;
 byte present = 0;
 byte data[12];
 byte addr[8];
 int Temp;
 if ( !ds.search(addr)) {
     //Serial.print("No more addresses.\n");
     ds.reset_search();
     return;
 }
 
 Serial.print("R=");  //R=28 Not sure what this is
 for( i = 0; i < 8; i++) {
   Serial.print(addr[i], HEX);
   Serial.print(" ");
 }

 if ( OneWire::crc8( addr, 7) != addr[7]) {
     Serial.print("CRC is not valid!\n");
     return;
 }
 
 if ( addr[0] != 0x28) {
     Serial.print("Device is not a DS18S20 family device.\n");
     return;
 }

 ds.reset();
 ds.select(addr);
 ds.write(0x44,1);         // start conversion, with parasite power on at the end
 
 delay(1000);     // maybe 750ms is enough, maybe not
 // we might do a ds.depower() here, but the reset will take care of it.
 
 present = ds.reset();
 ds.select(addr);    
 ds.write(0xBE);         // Read Scratchpad

 Serial.print("P=");  
 Serial.print(present,HEX);
 Serial.print(" ");
 for ( i = 0; i < 9; i++) {           // we need 9 bytes
   data[i] = ds.read();
   Serial.print(data[i], HEX);
   Serial.print("  ");
 }
 Temp=(data[1]<<8)+data[0];//take the two bytes from the response relating to temperature

 Temp=Temp>>4;//divide by 16 to get pure celcius readout

 //next line is Fahrenheit conversion
 Temp=Temp*1.8+32; // comment this line out to get celcius
 
 Serial.print("T=");//output the temperature to serial port
 Serial.print(Temp);
   Serial.print("  ");


 Serial.print(" CRC=");
 Serial.print( OneWire::crc8( data, 8), HEX);
 Serial.println();
}


teedeeus

#3
May 30, 2010, 04:51 am Last Edit: May 30, 2010, 05:57 pm by teedeeus Reason: 1
I'm trying to use the above code with a DS18B20 tempature sensor in Arduino 18 environment, but I can't get it to work.  It gets stuck in this loop:

 if ( !ds.search(addr)) {
     Serial.print("No more addresses.\n");
     ds.reset_search();
     return;

And just constantly prints out "No more addresses".  I'm not sure where I downloaded the 1-wire library from.  I think I may have an error in it - either that or it is not compatible with the latest Arduino environment.  Any help would be appreciated.  Thank you

-teedeeus

UPDATE:  I discovered this morning I was using the wrong resistor, so no need to reply to this post.  It's working.  That's what I get for trying to choose a part in dim light - duh!

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy