@@ -175,7 +175,7 @@ void DallasTemperature::writeScratchPad(const uint8_t* deviceAddress, const uint
175
175
_wire->write (WRITESCRATCH);
176
176
_wire->write (scratchPad[HIGH_ALARM_TEMP]); // high alarm temp
177
177
_wire->write (scratchPad[LOW_ALARM_TEMP]); // low alarm temp
178
- // DS18S20 does not use the configuration register
178
+ // DS1820 and DS18S20 have no configuration register
179
179
if (deviceAddress[0 ] != DS18S20MODEL) _wire->write (scratchPad[CONFIGURATION]); // configuration
180
180
_wire->reset ();
181
181
_wire->select (deviceAddress); // <--this line was missing
@@ -218,7 +218,7 @@ bool DallasTemperature::setResolution(const uint8_t* deviceAddress, uint8_t newR
218
218
ScratchPad scratchPad;
219
219
if (isConnected (deviceAddress, scratchPad))
220
220
{
221
- // DS18S20 has a fixed 9-bit resolution
221
+ // DS1820 and DS18S20 have no resolution configuration register
222
222
if (deviceAddress[0 ] != DS18S20MODEL)
223
223
{
224
224
switch (newResolution)
@@ -254,8 +254,7 @@ uint8_t DallasTemperature::getResolution()
254
254
// returns 0 if device not found
255
255
uint8_t DallasTemperature::getResolution (const uint8_t * deviceAddress)
256
256
{
257
- // this model has a fixed resolution of 9 bits but getTemp calculates
258
- // a full 12 bits resolution and we need 750ms convert time
257
+ // DS1820 and DS18S20 have no resolution configuration register
259
258
if (deviceAddress[0 ] == DS18S20MODEL) return 12 ;
260
259
261
260
ScratchPad scratchPad;
@@ -409,39 +408,50 @@ float DallasTemperature::getTempFByIndex(uint8_t deviceIndex)
409
408
return getTempF ((uint8_t *)deviceAddress);
410
409
}
411
410
412
- // reads scratchpad and returns the raw temperature (12bit)
411
+ // reads scratchpad and returns fixed-point temperature, scaling factor 2^-7
413
412
int16_t DallasTemperature::calculateTemperature (const uint8_t * deviceAddress, uint8_t * scratchPad)
414
413
{
415
- int16_t rawTemperature = (((int16_t )scratchPad[TEMP_MSB]) << 8 ) | scratchPad[TEMP_LSB];
414
+ int16_t fpTemperature =
415
+ (((int16_t ) scratchPad[TEMP_MSB]) << 11 ) |
416
+ (((int16_t ) scratchPad[TEMP_LSB]) << 3 );
416
417
417
- /* DS18S20
418
- Resolutions greater than 9 bits can be calculated using the data from
419
- the temperature, COUNT REMAIN and COUNT PER °C registers in the
420
- scratchpad. Note that the COUNT PER °C register is hard-wired to 16
421
- (10h). After reading the scratchpad, the TEMP_READ value is obtained
422
- by truncating the 0.5°C bit (bit 0) from the temperature data. The
418
+ /*
419
+ DS1820 and DS18S20 have a 9-bit temperature register.
420
+
421
+ Resolutions greater than 9-bit can be calculated using the data from
422
+ the temperature, and COUNT REMAIN and COUNT PER °C registers in the
423
+ scratchpad. The resolution of the calculation depends on the model.
424
+
425
+ While the COUNT PER °C register is hard-wired to 16 (10h) in a
426
+ DS18S20, it changes with temperature in DS1820.
427
+
428
+ After reading the scratchpad, the TEMP_READ value is obtained by
429
+ truncating the 0.5°C bit (bit 0) from the temperature data. The
423
430
extended resolution temperature can then be calculated using the
424
431
following equation:
425
432
426
433
COUNT_PER_C - COUNT_REMAIN
427
434
TEMPERATURE = TEMP_READ - 0.25 + --------------------------
428
435
COUNT_PER_C
429
436
430
- Simplified to integer arithmetic for a 12 bits value:
431
-
432
- TEMPERATURE = ((raw & 0xFFFE) << 3) - 4 + 16 - COUNT_REMAIN
437
+ Hagai Shatz simplified this to integer arithmetic for a 12 bits
438
+ value for a DS18S20, and James Cameron added legacy DS1820 support.
433
439
434
440
See - http://myarduinotoy.blogspot.co.uk/2013/02/12bit-result-from-ds18s20.html
435
441
*/
436
442
437
443
if (deviceAddress[0 ] == DS18S20MODEL)
438
- rawTemperature = ((rawTemperature & 0xFFFE ) << 3 ) + 12 - scratchPad[COUNT_REMAIN];
444
+ fpTemperature = ((fpTemperature & 0xfff0 ) << 3 ) - 16 +
445
+ (
446
+ ((scratchPad[COUNT_PER_C] - scratchPad[COUNT_REMAIN]) << 7 ) /
447
+ scratchPad[COUNT_PER_C]
448
+ );
439
449
440
- return rawTemperature ;
450
+ return fpTemperature ;
441
451
}
442
452
443
453
444
- // returns raw temperature in 1/16 degrees C or DEVICE_DISCONNECTED_RAW if the
454
+ // returns temperature in 1/128 degrees C or DEVICE_DISCONNECTED_RAW if the
445
455
// device's scratch pad cannot be read successfully.
446
456
// the numeric value of DEVICE_DISCONNECTED_RAW is defined in
447
457
// DallasTemperature.h. It is a large negative number outside the
@@ -639,22 +649,20 @@ bool DallasTemperature::alarmSearch(uint8_t* newAddr)
639
649
return true ;
640
650
}
641
651
642
- // returns true if device address has an alarm condition
643
- // TODO: can this be done with only TEMP_MSB REGISTER (faster)
644
- // if ((char) scratchPad[TEMP_MSB] <= (char) scratchPad[LOW_ALARM_TEMP]) return true;
645
- // if ((char) scratchPad[TEMP_MSB] >= (char) scratchPad[HIGH_ALARM_TEMP]) return true;
652
+ // returns true if device address might have an alarm condition
653
+ // (only an alarm search can verify this)
646
654
bool DallasTemperature::hasAlarm (const uint8_t * deviceAddress)
647
655
{
648
656
ScratchPad scratchPad;
649
657
if (isConnected (deviceAddress, scratchPad))
650
658
{
651
- float temp = calculateTemperature (deviceAddress, scratchPad);
659
+ char temp = calculateTemperature (deviceAddress, scratchPad) >> 7 ;
652
660
653
661
// check low alarm
654
- if (( char ) temp <= (char )scratchPad[LOW_ALARM_TEMP]) return true ;
662
+ if (temp <= (char )scratchPad[LOW_ALARM_TEMP]) return true ;
655
663
656
664
// check high alarm
657
- if (( char ) temp >= (char )scratchPad[HIGH_ALARM_TEMP]) return true ;
665
+ if (temp >= (char )scratchPad[HIGH_ALARM_TEMP]) return true ;
658
666
}
659
667
660
668
// no alarm
@@ -712,18 +720,18 @@ float DallasTemperature::rawToCelsius(int16_t raw)
712
720
{
713
721
if (raw <= DEVICE_DISCONNECTED_RAW)
714
722
return DEVICE_DISCONNECTED_C;
715
- // C = RAW/16
716
- return (float )raw * 0.0625 ;
723
+ // C = RAW/128
724
+ return (float )raw * 0.0078125 ;
717
725
}
718
726
719
727
// convert from raw to Fahrenheit
720
728
float DallasTemperature::rawToFahrenheit (int16_t raw)
721
729
{
722
730
if (raw <= DEVICE_DISCONNECTED_RAW)
723
731
return DEVICE_DISCONNECTED_F;
724
- // C = RAW/16
725
- // F = (C*1.8)+32 = (RAW/16 *1.8)+32 = (RAW*0.1125 )+32
726
- return ((float )raw * 0.1125 ) + 32 ;
732
+ // C = RAW/128
733
+ // F = (C*1.8)+32 = (RAW/128 *1.8)+32 = (RAW*0.0140625 )+32
734
+ return ((float )raw * 0.0140625 ) + 32 ;
727
735
}
728
736
729
737
#if REQUIRESNEW
0 commit comments