DS18S20 yields strange result

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

First of all - long time - no c.

I have been fiddling with the Dallas DS18S20 temperature sensor. The 1wire protocol has been nasty to implement mostly because of the quite strict timing requirements. However - it is now done and works great.

What the code does is:

every 2 seconds {
    for each device on the bus {
         do temperature conversion
         read the scratchpad
         convert scratchpad into temperature
    }
}

There was several very tricky "things" like
- setting up the read sample point to optimal location
-reading and re-reading the datasheet to finally find that the conversion time is 750 minniseconds
- etc...

Now, the code is made such that the OneWireDeviceScan calls function OneWireDevice for each device it can find on the bus. This works and I can insert/remove devices from the bus on the fly and the new devices are found properly.

Also, the ROM match and commanding works as I can see the scratchpad changing. Reader should also work as the CRC shows correct values but ....

I know I live here near the polar circle but still -71 degrees celcius feels like too much on the negative side.

If I warm the device the temperature climbs exactly as it should.

Text on a similar device (TO-92 case):
DALLAS
DS1820
0712C3
+369AE

Any ideas why the device is having such a negative attitude ?

Here is the output for 2 devices on the bus the other being warmed up:

OneWireDevice  : 10 75 40 86 01 08 00 6C                                        
Scratchpad     : BB FF 00 00 FF FF 01 10 E7 -E7                                 
Temperature    : -69                                                            
OneWireDevice  : 10 C8 47 8D 01 08 00 E4                                        
Scratchpad     : B9 FF 00 00 FF FF 02 10 34 -34                                 
Temperature    : -71                                                            
OneWireDevice  : 10 75 40 86 01 08 00 6C                                        
Scratchpad     : BB FF 00 00 FF FF 01 10 E7 -E7                                 
Temperature    : -69                                                            
OneWireDevice  : 10 C8 47 8D 01 08 00 E4                                        
Scratchpad     : B9 FF 00 00 FF FF 02 10 34 -34                                 
Temperature    : -71                                                            
OneWireDevice  : 10 75 40 86 01 08 00 6C                                        
Scratchpad     : BB FF 00 00 FF FF 02 10 B2 -B2                                 
Temperature    : -69                                                            
OneWireDevice  : 10 C8 47 8D 01 08 00 E4                                        
Scratchpad     : B9 FF 00 00 FF FF 02 10 34 -34                                 
Temperature    : -71                                                            
OneWireDevice  : 10 75 40 86 01 08 00 6C                                        
Scratchpad     : CD FF 00 00 FF FF 04 10 3E -3E                                 
Temperature    : -51                                                            
OneWireDevice  : 10 C8 47 8D 01 08 00 E4                                        
Scratchpad     : BB FF 00 00 FF FF 06 10 89 -89                                 
Temperature    : -69                                                            
OneWireDevice  : 10 75 40 86 01 08 00 6C                                        
Scratchpad     : F4 FF 00 00 FF FF 0F 10 88 -88                                 
Temperature    : -12                                                            
OneWireDevice  : 10 C8 47 8D 01 08 00 E4                                        
Scratchpad     : BC FF 00 00 FF FF 0D 10 7A -7A                                 
Temperature    : -68                                                            
OneWireDevice  : 10 75 40 86 01 08 00 6C                                        
Scratchpad     : 02 00 00 00 FF FF 09 10 90 -90                                 
Temperature    : 2                                                              
OneWireDevice  : 10 C8 47 8D 01 08 00 E4                                        
Scratchpad     : BC FF 00 00 FF FF 0B 10 D0 -D0                                 
Temperature    : -68                                                            
OneWireDevice  : 10 75 40 86 01 08 00 6C                                        
Scratchpad     : 10 00 00 00 FF FF 0F 10 E8 -E8                                 
Temperature    : 16                                                             
OneWireDevice  : 10 C8 47 8D 01 08 00 E4                                        
Scratchpad     : BD FF 00 00 FF FF 08 10 C6 -C6                                 
Temperature    : -67                                                            
OneWireDevice  : 10 75 40 86 01 08 00 6C                                        
Scratchpad     : 05 00 00 00 FF FF 03 10 A7 -A7                                 
Temperature    : 5                                                              
OneWireDevice  : 10 C8 47 8D 01 08 00 E4                                        
Scratchpad     : BC FF 00 00 FF FF 09 10 41 -41                                 
Temperature    : -68                                                            

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

1) The scratchpad is only 9 bytes, so I'm a little confused that you have 10 in your output.

2) Not sure if it's relevant, but the 8 byte device ID you're showing looks backwards (the 0x10 family ID is the least significant byte).

3) Are you going through the whole sequence each measurement of (Reset - Match Rom - Convert T - wait - Read Scratchpad)?

Maybe helpful, maybe not...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

basil| wrote:
1) The scratchpad is only 9 bytes, so I'm a little confused that you have 10 in your output.
The 10. byte is the CRC calculated - so one can see that the last byte received and the calculated CRC are the same.

basil| wrote:
2) Not sure if it's relevant, but the 8 byte device ID you're showing looks backwards (the 0x10 family ID is the least significant byte).
Yes it is. The first byte on the log output is the LSB last being MSB.

basil| wrote:
3) Are you going through the whole sequence each measurement of (Reset - Match Rom - Convert T - wait - Read Scratchpad)?
Actually Yes. One could propably do Skip ROM and sort of broadcast the conversion but to read the individual scratchpads the match rom has to be done for each device. If there are lot of devices on the bus broadcasting the conversion saves 750mS for each additional device.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@eskoilola

Have a look here , this is a nice project
http://www.siwawi.arubi.uni-kl.d...

Btw: i do

On every second
  if even
    send convert temp
  else
    read scratchpad

Then i get the 750ms conversion delay for free

/Bingo

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Some update to this horse beaten to death:

Everything works just fine but the operation does NOT match with the datasheet of DS18S20. The temperature conversion result seems to have a constant negative "bias". This is easy to compensate - I just hate when devices do not work like the datasheet claims them to work.

The temperature conversion code is now:

// -----------------------------------------------------------------------
// DsTemperature.c
// -----------------------------------------------------------------------
#include 
#include "OneWire.h"
#include "Imath.h"
#include "OneWire_Private.h"

// -----------------------------------------------------------------------
// DS18S20
// -----------------------------------------------------------------------
static	int16_t			temperatureDs18s20	( onewire_ds1820_t * aData ) {
	word_byte_t	temperature;
	uint16_t	fract;

	// -------------------------------------------------------------------
	// Collect the data
	// -------------------------------------------------------------------
	temperature.avr.lo = aData->data.templ;
	temperature.avr.hi = aData->data.temph;

	// -------------------------------------------------------------------
	// There seems to be a constant negative bias - compensate for it
	// -------------------------------------------------------------------
	temperature.word += (uint16_t)112;

	// -------------------------------------------------------------------
	// Truncate the lowest bit as the manual states
	// -------------------------------------------------------------------
	temperature.word &= (uint16_t)0xFFFE;

	// -------------------------------------------------------------------
	// Multiply the result by 100 to get correct results with the fraction
	// -------------------------------------------------------------------
	temperature.int16 *= (int16_t)100;

	// -------------------------------------------------------------------
	// Get the fraction multiplied by 100
	// -------------------------------------------------------------------
	fract =  (uint16_t)0x0010 - (uint16_t)aData->data.count_remain;
	fract *= (uint16_t)100;
	fract /= (uint16_t)0x0010;
	fract -= (uint16_t)25;

	// -------------------------------------------------------------------
	// Add fraction and the actual temperature
	// -------------------------------------------------------------------
	temperature.int16 += (int16_t)fract;

	// -------------------------------------------------------------------
	// scaling is now 200 steps / degree
	// we want 10 steps / degree
	// -> divide by 20.
	// -------------------------------------------------------------------
	temperature.int16 /= (int16_t)20;

	return	temperature.int16;
}

// -----------------------------------------------------------------------
// Convert scratchpad into temperature
// -----------------------------------------------------------------------
extern	int16_t			DsTemperature		( onewire_family_t aFamily,
											  onewire_ds1820_t * aData ) {
	uint16_t	temperature;

	switch	( aFamily ) {
		case	onewire_family_ds18s20:
		temperature = temperatureDs18s20( aData );
		break;

		default:
		temperature = 0;
		break;
	}	

	return	temperature;
}

// -----------------------------------------------------------------------
// EOF: DsTemperature.c
// -----------------------------------------------------------------------

Attachment(s):