Skip to content

Commit

Permalink
Merge pull request #6 from hagai-shatz/master
Browse files Browse the repository at this point in the history
New API for raw value (int of 1/16 degree)
  • Loading branch information
milesburton committed Mar 9, 2013
2 parents 4aa66ca + e1cdffb commit f8d1a4d
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 72 deletions.
144 changes: 80 additions & 64 deletions DallasTemperature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,8 @@ uint8_t DallasTemperature::getResolution()
// returns 0 if device not found
uint8_t DallasTemperature::getResolution(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
if (deviceAddress[0] == DS18S20MODEL) return 12;

ScratchPad scratchPad;
Expand Down Expand Up @@ -405,78 +407,73 @@ float DallasTemperature::getTempCByIndex(uint8_t deviceIndex)
// Fetch temperature for device index
float DallasTemperature::getTempFByIndex(uint8_t deviceIndex)
{
return toFahrenheit(getTempCByIndex(deviceIndex));
DeviceAddress deviceAddress;
getAddress(deviceAddress, deviceIndex);
return getTempF((uint8_t*)deviceAddress);
}

// reads scratchpad and returns the temperature in degrees C
float DallasTemperature::calculateTemperature(uint8_t* deviceAddress, uint8_t* scratchPad)
// reads scratchpad and returns the raw temperature (12bit)
int16_t DallasTemperature::calculateTemperature(uint8_t* deviceAddress, uint8_t* scratchPad)
{
int16_t rawTemperature = (((int16_t)scratchPad[TEMP_MSB]) << 8) | scratchPad[TEMP_LSB];

switch (deviceAddress[0])
{
case DS18B20MODEL:
case DS1822MODEL:
switch (scratchPad[CONFIGURATION])
{
case TEMP_12_BIT:
return (float)rawTemperature * 0.0625;
break;
case TEMP_11_BIT:
return (float)(rawTemperature >> 1) * 0.125;
break;
case TEMP_10_BIT:
return (float)(rawTemperature >> 2) * 0.25;
break;
case TEMP_9_BIT:
return (float)(rawTemperature >> 3) * 0.5;
break;
}
break;
case DS18S20MODEL:
/*
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
extended resolution temperature can then be calculated using the
following equation:
COUNT_PER_C - COUNT_REMAIN
TEMPERATURE = TEMP_READ - 0.25 + --------------------------
COUNT_PER_C
*/

// Good spot. Thanks Nic Johns for your contribution
return (float)(rawTemperature >> 1) - 0.25 +((float)(scratchPad[COUNT_PER_C] - scratchPad[COUNT_REMAIN]) / (float)scratchPad[COUNT_PER_C] );
break;
}
/* 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
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
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];

return rawTemperature;
}

// returns temperature in degrees C or DEVICE_DISCONNECTED if the

// returns raw temperature in 1/16 degrees C or DEVICE_DISCONNECTED_RAW if the
// device's scratch pad cannot be read successfully.
// the numeric value of DEVICE_DISCONNECTED is defined in
// the numeric value of DEVICE_DISCONNECTED_RAW is defined in
// DallasTemperature.h. It is a large negative number outside the
// operating range of the device
float DallasTemperature::getTempC(uint8_t* deviceAddress)
int16_t DallasTemperature::getTemp(uint8_t* deviceAddress)
{
// TODO: Multiple devices (up to 64) on the same bus may take
// some time to negotiate a response
// What happens in case of collision?

ScratchPad scratchPad;
if (isConnected(deviceAddress, scratchPad)) return calculateTemperature(deviceAddress, scratchPad);
return DEVICE_DISCONNECTED;
return DEVICE_DISCONNECTED_RAW;
}

// returns temperature in degrees F
// TODO: - when getTempC returns DEVICE_DISCONNECTED
// -127 gets converted to -196.6 F
// returns temperature in degrees C or DEVICE_DISCONNECTED_C if the
// device's scratch pad cannot be read successfully.
// the numeric value of DEVICE_DISCONNECTED_C is defined in
// DallasTemperature.h. It is a large negative number outside the
// operating range of the device
float DallasTemperature::getTempC(uint8_t* deviceAddress)
{
return rawToCelsius(getTemp(deviceAddress));
}

// returns temperature in degrees F or DEVICE_DISCONNECTED_F if the
// device's scratch pad cannot be read successfully.
// the numeric value of DEVICE_DISCONNECTED_F is defined in
// DallasTemperature.h. It is a large negative number outside the
// operating range of the device
float DallasTemperature::getTempF(uint8_t* deviceAddress)
{
return toFahrenheit(getTempC(deviceAddress));
return rawToFahrenheit(getTemp(deviceAddress));
}

// returns true if the bus requires parasite power
Expand Down Expand Up @@ -507,7 +504,7 @@ the next temperature conversion.
*/

// sets the high alarm temperature for a device in degrees celsius
// sets the high alarm temperature for a device in degrees Celsius
// accepts a float, but the alarm resolution will ignore anything
// after a decimal point. valid range is -55C - 125C
void DallasTemperature::setHighAlarmTemp(uint8_t* deviceAddress, char celsius)
Expand All @@ -524,7 +521,7 @@ void DallasTemperature::setHighAlarmTemp(uint8_t* deviceAddress, char celsius)
}
}

// sets the low alarm temperature for a device in degreed celsius
// sets the low alarm temperature for a device in degrees Celsius
// accepts a float, but the alarm resolution will ignore anything
// after a decimal point. valid range is -55C - 125C
void DallasTemperature::setLowAlarmTemp(uint8_t* deviceAddress, char celsius)
Expand All @@ -547,7 +544,7 @@ char DallasTemperature::getHighAlarmTemp(uint8_t* deviceAddress)
{
ScratchPad scratchPad;
if (isConnected(deviceAddress, scratchPad)) return (char)scratchPad[HIGH_ALARM_TEMP];
return DEVICE_DISCONNECTED;
return DEVICE_DISCONNECTED_C;
}

// returns a char with the current low alarm temperature or
Expand All @@ -556,7 +553,7 @@ char DallasTemperature::getLowAlarmTemp(uint8_t* deviceAddress)
{
ScratchPad scratchPad;
if (isConnected(deviceAddress, scratchPad)) return (char)scratchPad[LOW_ALARM_TEMP];
return DEVICE_DISCONNECTED;
return DEVICE_DISCONNECTED_C;
}

// resets internal variables used for the alarm search
Expand Down Expand Up @@ -617,7 +614,7 @@ bool DallasTemperature::alarmSearch(uint8_t* newAddr)
if (alarmSearchAddress[ibyte] & ibit) a = 1;
else
{
// Only 0s count as pending junctions, we've already exhasuted the 0 side of 1s
// Only 0s count as pending junctions, we've already exhausted the 0 side of 1s
a = 0;
done = 0;
lastJunction = i;
Expand Down Expand Up @@ -701,32 +698,51 @@ void DallasTemperature::defaultAlarmHandler(uint8_t* deviceAddress)

#endif

// Convert float celsius to fahrenheit
// Convert float Celsius to Fahrenheit
float DallasTemperature::toFahrenheit(float celsius)
{
return (celsius * 1.8) + 32;
}

// Convert float fahrenheit to celsius
// Convert float Fahrenheit to Celsius
float DallasTemperature::toCelsius(float fahrenheit)
{
return (fahrenheit - 32) / 1.8;
}

// convert from raw to Celsius
float DallasTemperature::rawToCelsius(const int16_t raw)
{
if (raw <= DEVICE_DISCONNECTED_RAW)
return DEVICE_DISCONNECTED_C;
// C = RAW/16
return (float)raw * 0.0625;
}

// convert from raw to Fahrenheit
float DallasTemperature::rawToFahrenheit(const int16_t raw)
{
if (raw <= DEVICE_DISCONNECTED_RAW)
return DEVICE_DISCONNECTED_F;
// C = RAW/16
// F = (C*1.8)+32 = (RAW/16*1.8)+32 = (RAW*0.1125)+32
return ((float)raw * 0.1125) + 32;
}

#if REQUIRESNEW

// MnetCS - Allocates memory for DallasTemperature. Allows us to instance a new object
void* DallasTemperature::operator new(unsigned int size) // Implicit NSS obj size
{
void * p; // void pointer
p = malloc(size); // Allocate memory
memset((DallasTemperature*)p,0,size); // Initalise memory
memset((DallasTemperature*)p,0,size); // Initialise memory

//!!! CANT EXPLICITLY CALL CONSTRUCTOR - workaround by using an init() methodR - workaround by using an init() method
return (DallasTemperature*) p; // Cast blank region to NSS pointer
}

// MnetCS 2009 - Unallocates the memory used by this instance
// MnetCS 2009 - Free the memory used by this instance
void DallasTemperature::operator delete(void* p)
{
DallasTemperature* pNss = (DallasTemperature*) p; // Cast to NSS pointer
Expand Down
28 changes: 20 additions & 8 deletions DallasTemperature.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#define DS18S20MODEL 0x10
#define DS18B20MODEL 0x28
#define DS1822MODEL 0x22
#define DS1825MODEL 0x3B

// OneWire commands
#define STARTCONVO 0x44 // Tells device to take a temperature reading and put it on the scratchpad
Expand Down Expand Up @@ -53,7 +54,9 @@
#define TEMP_12_BIT 0x7F // 12 bit

// Error Codes
#define DEVICE_DISCONNECTED -127
#define DEVICE_DISCONNECTED_C -127
#define DEVICE_DISCONNECTED_F -196.6
#define DEVICE_DISCONNECTED_RAW -2032

typedef uint8_t DeviceAddress[8];

Expand All @@ -63,7 +66,7 @@ class DallasTemperature

DallasTemperature(OneWire*);

// initalise bus
// initialise bus
void begin(void);

// returns the number of devices found on the bus
Expand Down Expand Up @@ -100,7 +103,7 @@ class DallasTemperature
// set global resolution to 9, 10, 11, or 12 bits
void setResolution(uint8_t);

// returns the device resolution, 9-12
// returns the device resolution: 9, 10, 11, or 12 bits
uint8_t getResolution(uint8_t*);

// set resolution of a device to 9, 10, 11, or 12 bits
Expand All @@ -123,6 +126,9 @@ class DallasTemperature
// sends command for one device to perform a temperature conversion by index
bool requestTemperaturesByIndex(uint8_t);

// returns temperature raw value (12 bit integer of 1/16 degrees C)
int16_t getTemp(uint8_t*);

// returns temperature in degrees C
float getTempC(uint8_t*);

Expand Down Expand Up @@ -183,15 +189,21 @@ class DallasTemperature

#endif

// convert from celcius to farenheit
// convert from Celsius to Fahrenheit
static float toFahrenheit(const float);

// convert from farenheit to celsius
// convert from Fahrenheit to Celsius
static float toCelsius(const float);

// convert from raw to Celsius
static float rawToCelsius(const int16_t);

// convert from raw to Fahrenheit
static float rawToFahrenheit(const int16_t);

#if REQUIRESNEW

// initalize memory area
// initialize memory area
void* operator new (unsigned int);

// delete memory reference
Expand Down Expand Up @@ -221,8 +233,8 @@ class DallasTemperature
// Take a pointer to one wire instance
OneWire* _wire;

// reads scratchpad and returns the temperature in degrees C
float calculateTemperature(uint8_t*, uint8_t*);
// reads scratchpad and returns the raw temperature
int16_t calculateTemperature(uint8_t*, uint8_t*);

void blockTillConversionComplete(uint8_t*,uint8_t*);

Expand Down

0 comments on commit f8d1a4d

Please sign in to comment.