Skip to content

Commit

Permalink
restore support for DS1820
Browse files Browse the repository at this point in the history
- the DS1820 (circa 1998) is still in use in some temperature
  networks, and can be identified by the double height PR35 package,
  and a scratchpad COUNT_PER_C register value that changes during
  operation, but not by the family code in the device address,

- fixes a regression introduced in e1cdffb, resulting in sawtooth
  temperature graphs for a linear temperature change, caused by using
  a fixed COUNT_PER_C register value for DS18S20 and therefore DS1820,

- tested with both DS18S20 and DS1820 sensors.
  • Loading branch information
quozl committed Jan 15, 2014
1 parent e218270 commit 1386d85
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 15 deletions.
36 changes: 22 additions & 14 deletions DallasTemperature.cpp
Expand Up @@ -175,7 +175,7 @@ void DallasTemperature::writeScratchPad(const uint8_t* deviceAddress, const uint
_wire->write(WRITESCRATCH);
_wire->write(scratchPad[HIGH_ALARM_TEMP]); // high alarm temp
_wire->write(scratchPad[LOW_ALARM_TEMP]); // low alarm temp
// DS18S20 does not use the configuration register
// DS1820 and DS18S20 have no configuration register
if (deviceAddress[0] != DS18S20MODEL) _wire->write(scratchPad[CONFIGURATION]); // configuration
_wire->reset();
_wire->select(deviceAddress); //<--this line was missing
Expand Down Expand Up @@ -218,7 +218,7 @@ bool DallasTemperature::setResolution(const uint8_t* deviceAddress, uint8_t newR
ScratchPad scratchPad;
if (isConnected(deviceAddress, scratchPad))
{
// DS18S20 has a fixed 9-bit resolution
// DS1820 and DS18S20 have no resolution configuration register
if (deviceAddress[0] != DS18S20MODEL)
{
switch (newResolution)
Expand Down Expand Up @@ -254,8 +254,7 @@ uint8_t DallasTemperature::getResolution()
// returns 0 if device not found
uint8_t DallasTemperature::getResolution(const uint8_t* deviceAddress)
{
// this model has a fixed resolution of 9 bits but getTemp calculates
// a full 12 bits resolution and we need 750ms convert time
// DS1820 and DS18S20 have no resolution configuration register
if (deviceAddress[0] == DS18S20MODEL) return 12;

ScratchPad scratchPad;
Expand Down Expand Up @@ -414,28 +413,37 @@ int16_t DallasTemperature::calculateTemperature(const uint8_t* deviceAddress, ui
{
int16_t rawTemperature = (((int16_t)scratchPad[TEMP_MSB]) << 8) | scratchPad[TEMP_LSB];

/* DS18S20
Resolutions greater than 9 bits can be calculated using the data from
the temperature, COUNT REMAIN and COUNT PER °C registers in the
scratchpad. Note that the COUNT PER °C register is hard-wired to 16
(10h). After reading the scratchpad, the TEMP_READ value is obtained
by truncating the 0.5°C bit (bit 0) from the temperature data. The
/*
DS1820 and DS18S20 have a 9-bit temperature register.
Resolutions greater than 9-bit can be calculated using the data from
the temperature, and COUNT REMAIN and COUNT PER °C registers in the
scratchpad. The resolution of the calculation depends on the model.
While the COUNT PER °C register is hard-wired to 16 (10h) in a
DS18S20, it changes with temperature in DS1820.
After reading the scratchpad, the TEMP_READ value is obtained by
truncating the 0.5°C bit (bit 0) from the temperature data. The
extended resolution temperature can then be calculated using the
following equation:
COUNT_PER_C - COUNT_REMAIN
TEMPERATURE = TEMP_READ - 0.25 + --------------------------
COUNT_PER_C
Simplified to integer arithmetic for a 12 bits value:
TEMPERATURE = ((raw & 0xFFFE) << 3) - 4 + 16 - COUNT_REMAIN
Hagai Shatz simplified this to integer arithmetic for a 12 bits
value for a DS18S20, and James Cameron added legacy DS1820 support.
See - http://myarduinotoy.blogspot.co.uk/2013/02/12bit-result-from-ds18s20.html
*/

if (deviceAddress[0] == DS18S20MODEL)
rawTemperature = ((rawTemperature & 0xFFFE) << 3) + 12 - scratchPad[COUNT_REMAIN];
rawTemperature = ((rawTemperature & 0xfffe) << 3) - 2 +
(
((scratchPad[COUNT_PER_C] - scratchPad[COUNT_REMAIN]) << 4) /
scratchPad[COUNT_PER_C]
);

return rawTemperature;
}
Expand Down
2 changes: 1 addition & 1 deletion DallasTemperature.h
Expand Up @@ -22,7 +22,7 @@
#include <OneWire.h>

// Model IDs
#define DS18S20MODEL 0x10
#define DS18S20MODEL 0x10 // also DS1820
#define DS18B20MODEL 0x28
#define DS1822MODEL 0x22
#define DS1825MODEL 0x3B
Expand Down
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -10,6 +10,7 @@ This library supports the following devices :
* DS18B20
* DS18S20 - Please note there appears to be an issue with this series.
* DS1822
* DS1820


You will need a pull-up resistor of about 5 KOhm between the 1-Wire data line
Expand Down

0 comments on commit 1386d85

Please sign in to comment.