Interfacing Arduino with DS18S20

I did some searching and came across Miles Burton's Dallas Temperature Library here:

http://milesburton.com/wiki/index.php?title=Dallas_Temperature_Control_Library

Im running his sample code, and using a 4.7k resistor as he specifies. When I watch the serial terminal, I get:

Dallas Temperature IC Control Library 1.0. Miles Burton 3.00C 3.00C 3.00C -- repeating --

If I touch the sensor it goes up no further than 3.70C. I know for sure that my room is hotter than that; where should I begin? Im still quite new to my Arduino

EDIT I have tried parasitic and normal power modes but that didnt make a difference.

The example code from this works:

http://www.arduino.cc/playground/Learning/OneWire

If you can't get that to work for you, then there is probably a wiring error (pretty simple wiring) or a defective part.

That will at least get you started from a known good point.

I don't have a RAR program to unarchive the sources but... if you're getting 3.00C for room temperature then the program is confusing your 18S20 for an 18B20. You should be printing 24.00C -- your reading is one-eighth of what it should be because the 18S20 has only 9-bits of precision and the 18B20 can have upto 12-bits, a difference of 3-bits or a factor of 2*2*2 or 8.

Do as EmilyJane suggests and use the tried and true program from the example code from the playground. I suspect that your wiring is just fine!

-Rusty-

Hi guys, thanks for the reply!

I ran the OneWire sample code and this is my output in the serial terminal:

R=10 8E 26 72 1 8 0 14 P=1 30 0 4B 46 FF FF F 10 B8 CRC=B8 3.00 No more addresses. R=10 8E 26 72 1 8 0 14 P=1 30 0 4B 46 FF FF E 10 7C CRC=7C 3.00 No more addresses. R=10 8E 26 72 1 8 0 14 P=1 30 0 4B 46 FF FF E 10 7C CRC=7C 3.00 No more addresses. R=10 8E 26 72 1 8 0 14 P=1 30 0 4B 46 FF FF E 10 7C CRC=7C 3.00 No more addresses. R=10 8E 26 72 1 8 0 14 P=1 30 0 4B 46 FF FF E 10 7C CRC=7C 3.00 No more addresses. R=10 8E 26 72 1 8 0 14 P=1 30 0 4B 46 FF FF E 10 7C CRC=7C 3.00

Also, here is a link to the Dallas Temperature source, but zipped instead of rar'd (hopefully redistributing it is okay): http://rapidshare.com/files/254282141/DallasTemperature.zip.html

EDIT I noticed something else: the bag that I received the chips in (from Maxim) says DS18S20 for the part #, but the sensors themselves say DS1820 - if it makes any difference.

EDIT 2 I noticed on Miles Burton's library page, he says there is a bug with the S series, and links to a bugzilla page. I tried registereing but I havent received an activation email. Perhaps this is the bug he meant?

According to the data from the Device Address and the Scratchpad,
this device is an 1820 or 18S20, not an 18B20. From the scratchpad
data, 30 0 (which is HEX), the temperature for this device is 48/2
or 24-degrees Celcius, as I stated before.

Again, this software is incorrectly believing that the temperature sensors
are 18B20 and thus incorrectly displaying the temperature.

To correct this the software in the temperature conversion routine needs
to examine the first byte of the device address and calculate the temperature appropriately:

    float temp;

    if (devices[x].devaddr[0] == OW_FAMILY_10) {
        temp = ((scratchpad[1] << 8) + scratchpad[0]) / 2.0;
    }
    else if (devices[x].devaddr[0] == OW_FAMILY_28) {
        temp = ((scratchpad[1] << 8) + scratchpad[0]) / 16.0;
    }

-Rusty-

Where do I put the code that you attached? Thanks

I can't tell you exactly since I'm not really in the mood to play games with [u]rapidshare.com[/u] to download the .zip file and look at the source.

As I said before: To correct this, the software in the temperature conversion routine needs to examine the first byte of the device address and calculate the temperature appropriately:

This will be in the function that reads the temperature from scratchpad memory that's obtained from the sensor.

Im used to downloading things off RapidShare, I guess I dont mind waiting a few seconds to get the file as much as you do. I tossed the file on my server, so here’s a direct link if you find yourself bored ;D

http://skoba.no-ip.org/adam/DallasTemperature.zip

Here is the code that reads the temperature (from what I can tell - Im not very good at programming, nor do I have that much experience with it):

void DallasTemperature::requestTemperature(void)
{
  pDataWire->reset();
  pDataWire->select(arSlaveAddr);
  pDataWire->write(READSCRATCH);         // Read Scratchpad
}

float DallasTemperature::getTemperature() // ~ Double word, expensive
{
    // If we're ready to rock, begin communication channel
    if(isValid()==SLAVEGOOD){
        beginCommunication();
    }else{
        return 0;
    }

    requestTemperature(); // Send appropriate command


  // Originally you would read all n bytes (12~). We only need the first two
  byte lowByte = pDataWire->read();
  byte highByte = pDataWire->read();


    // TODO: Doesn't consider negative.
  int reading = (highByte<<8) + lowByte; // Concat word

  //TODO fix me, should negate
  if (reading & 0x8000) reading = (reading ^ 0xffff) + 1; // 2's comp
  float temp = (6 * reading) + reading / 4;    // multiply by (100 * 0.0625) or 6.25


  return temp/100;    // Divide by 100 to gain decimal.

}

Look in S20Series.CPP and its associated files.

I'm not sure why you are using this library as it doesn't seem to deliver on its promise to improve on the one in the official library. I'll admit OneWire has its shortcomings but this error implies the author of DallasTemperature hasn't done much quality control.

Im using it because the code for displaying the temperature is much simpler than the sample code for the OneWire library

In S20Series.cpp I tried changing

  // TODO: Doesn't consider negative.
  float reading = (highByte<<8) + lowByte; // Concat word


  return reading/16;    // Calculate celcius

to:

  // TODO: Doesn't consider negative.
  float reading = (highByte<<8) + lowByte; // Concat word


  return reading/2;    // Calculate celcius

But it didnt change anything. Are there any special steps I need to take when I change source for it to compile the new code?

Delete S20Series.o

Edit: Actually, delete all the .o files in the DallasTemperature folder just to be on the safe side.

I tried deleting all the O files, and they were recreated when I compiled, but the change I made still didnt make a difference. Perhaps the library isnt differentiating between devices in the first place? It looks like he has different pieces of code for different devices, it seems reasonable to me that perhaps its always loading one set of code no matter what device it detects.

Hmmm, that sounds like the problem to me, too. maybe I’ll plow through his code and see if I can find the problem. It’s a shame you are having so much trouble.

Its kind of a pain but I never expected things to work perfectly right from the start. Playing around is what helps me learn and makes things more fun. Besides, it gave me some time to experiment with some code to toggle a LED on and off.

I appreciate the effort youre putting into this to help me. Thanks!

As long as you are having fun, every thing is good.

I've taken a look at the DallasTemperature library and I can't see that the strategy for a different sensor is ever used. It looks like it always treats the sensor like a DS 18B20.

It weird, going through this code has me craving Italian. I think I'll go have a little dinner.

Assembler is really my strong suit. I'll bet one of the Arduino code gurus can figure it out.

Thanks for all your help! hopefully one of them stumbles across this thread.

I don’t know about craving Italian but that code is causing my stomach
to make all sorts of scary noises. :-\ The dogs ran away when I was
looking at the code as well as the Playground page for the OneWire.
Can’t say I understand the need to override the ‘new’ and ‘delete’
operators in DallasTemperature.cpp. :o

And that whole point of testing a sign bit is bogus since the two bytes
from the scratchpad already represent a 2’s complement number.
The number is sign extended regardless of the version of 1820, S, B,
or “plain” as well as the 1822.

If someone is hellbent on using the DallasTemperature class, then try
replacing the end of DallasTemperature::getTemperature() with this
(the first lines down to the TODO: are the same):

  // Originally you would read all n bytes (12~). We only need the first two
  byte lowByte = pDataWire->read();
  byte highByte = pDataWire->read();

  // TODO: Doesn't consider negative.
  // RH -- Yes it does!
  float reading = (highByte<<8) + lowByte; // Concat word

  if ((arSlaveAddr[0] == DS18B20MODEL)
        || (arSlaveAddr[0] == DS1822MODEL))
     return (reading/16.0);
  else          // presuming either 18S20 or 1820 (old)
      return (reading/2.0);
}

Certainly this can be simplified slightly but it’s easier this way.

@EmilyJane: yer right, the code doesn’t appear to really distinguish
between the different OneWire families. The whole DallasTemperature()
class, to me, appears rather convoluted.

@SpikedCola: The various times I tried to download from RapidShare it
always told me to wait 2-minutes (not a few seconds!) due to their server
load BUT if I wanted to pay some money (and become a member) I
would get the download quicker. That’s the game I wouldn’t play. With
a 4- to 5-megabit/sec pipe here at the house… I wouldn’t have to wait if
they have just given me the “frakkin” file.

-Rusty-

Ahh sorry my mistake! Typically, for small files like that they dont make you wait, I didnt realize it was giving you a countdown timer or I would have given you the direct link in the first place. ::)

Also, thanks for the code snippet! That fixed it! One question with your description though. I know what a 2's compliment version of a binary number is from digital class, but what do you mean it's sign-extended?

Would you have any idea how I would implement his library for more than one sensor on the bus? Right now I went with one sensor per digital pin and just initialized DallasTemperature twice.

Rusty, that looks like a good solution to me. I don't feel quite as dumb now either. :)

I think all that nonsense about the sign bit is a remnant of the example code in the original OneWire library.

SpikedCola, what Rusty is referring to is that the temperature reading from the sensor scratchpad is already sign extended into the most significant bit therefore it doesn't require any extra work to handle negative temperatures.

Also, if you look at the example in the original library you might think you have to work harder to print floats whereas the latest Print class handles floats automatically, albeit to only two decimal places.

RumAndCoke :-)

If you don't have many temperature sensors and can spare the RAM, sure... put sensors on separate pins. At least you don't have to use the search algorithm to identify the sensors.

Otherwise, you do a search, make a list of all the sensors on a line, and then tell each to do a conversion, wait, and read the temperature.

Glad yer up and running right!