Let's start with something that is known to work. The code below works on a Duemilanove wired as described here.
For parasite power the DS18B20 is wired so that the two outer leads are connected to ground. The middle lead has a 1.5k pullup resistor to +5V. The middle lead is also connected to pin 8 on the Arduino. Then run this code:
#include <OneWire.h>
// http://datasheets.maxim-ic.com/en/ds/DS18B20.pdf
// OneWire DS18S20, DS18B20, DS1822 Temperature Example
//
// http://www.pjrc.com/teensy/td_libs_OneWire.html
// The two bugs in the conversion of the temperature have been fixed.
// The first bug didn't handle the precision correctly for anything
// other than 12 bits.
// The second bug was that the temperature was converted as an
// unsigned int which meant that it wouldn't convert a negative
// temperature correctly.
OneWire ds(8);
// SELECT a precision here
// t_precision #bits - delay(ms)
// 0 9 - 93.75
// 1 10 - 187.5
// 2 11 - 375
// 3 12 - 750
#define ds18b20_PRECISION 2
unsigned char t_precision = ds18b20_PRECISION;
// DS18B20 address data
byte addr[8][8];
byte data[12];
const unsigned char t_mask[4] = {
0x7, 0x3, 0x1, 0x0};
void print_rom(byte *p)
{
Serial.print("ROM =");
for(int i = 0; i < 8; i++) {
Serial.write(' ');
if(*p < 10)Serial.print(" ");
Serial.print(*p++, HEX);
}
Serial.println(" ");
}
void setup(void)
{
byte i,numdev;
byte present = 0;
byte type_s;
float celsius, fahrenheit;
Serial.begin(9600);
i = 0;
Serial.println("");
Serial.println("");
while(ds.search(addr[i])) {
if (OneWire::crc8(addr[i], 7) != addr[i][7]) {
print_rom(addr[i]);
Serial.println("CRC is not valid! - ignored");
continue;
}
print_rom(addr[i]);
i++;
}
if(i == 0) {
Serial.println("Nothing found");
Serial.println();
ds.reset_search();
delay(250);
return;
}
numdev = i;
for(int j=0;j<numdev;j++) {
Serial.println();
// This clears the alarm registers and sets the precision
ds.select(addr[j]);
ds.write(0x4E,0);
// write zero into the alarm registers
ds.write(0,0);
ds.write(0,0);
// and write t_precision into the configuration register
// to select the precision of the temperature
ds.write(t_precision << 5,0);
// Write them to the EEPROM
ds.write(0x48,1);
delay(20);
ds.depower();
// the first ROM byte indicates which chip
switch (addr[j][0]) {
case 0x10:
Serial.print(" Chip = DS18S20 "); // or old DS1820
type_s = 1;
break;
case 0x28:
Serial.print(" Chip = DS18B20 ");
type_s = 0;
break;
case 0x22:
Serial.print(" Chip = DS1822 ");
type_s = 0;
break;
default:
Serial.println("Device is not a DS18x20 family device.");
continue;
}
print_rom(addr[j]);
ds.reset();
ds.select(addr[j]);
#define PARASITE
#ifdef PARASITE
ds.write(0x44,1); // start conversion, with parasite power on at the end
#else
ds.write(0x44,0);
#endif
delay(1000);
// we might do a ds.depower() here, but the reset will
// take care of it.
present = ds.reset();
ds.select(addr[j]);
ds.write(0xBE,0); // Read Scratchpad
Serial.print("present=");
Serial.print(present,HEX);
Serial.print(" prec=");
Serial.print(t_precision);
Serial.print(" Data = ");
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();
// BUG - this must NOT be unsigned otherwise it won't handle
// negative temperatures.
int raw = (data[1] << 8) | data[0];
// The original version of this code had a bad bug here which
// only worked when it was reading with 12-bit precision.
// This code fixes it (and emailed the author).
// int cfg = (data[4] & 0x60) >> 5;
// For now, override the precision stored in the device until I can
// figure out why the code is not setting it.
int cfg = t_precision;
raw &= ~t_mask[cfg];
celsius = (float) raw / 16.0;
Serial.print(" Temperature = ");
Serial.print(celsius,4);
Serial.println(" Celsius");
// fahrenheit = celsius * 1.8 + 32.0;
// Serial.print(fahrenheit);
// Serial.println(" Fahrenheit");
} // END OF FOR J LOOP
}
void loop(void)
{
}
It produces this output:
ROM = 28 B9 E6 79 3 0 0 16
Chip = DS18B20 ROM = 28 B9 E6 79 3 0 0 16
present=1 prec=2 Data = 53 1 4B 46 7F FF D 10 E9 CRC=E9
Temperature = 21.1250 Celsius
This code scans the bus so you don't need to know the address of the chip.
Pete