I am using the DallasTemperature.h successfully, no complaints. However, there are a number of cases in my control software where I only need to use the integer value of the temperature, which would also allow me to store my 40 variables in a smaller index.
I noticed that if the 12-bit temperature is read as a two-byte integer, it could be shifted left 4 bits and the high byte would contain the integer of the temperature and the low byte would contain the fraction. This would also preserve the sign bit. I am only smart enough to use the function that returns the temperature as a float:
The DallasTemperature.h and DallasTemperature.cpp is a bit difficult to follow. Is there a function that returns the temperature as an integer, or is there a simple way to convert the floating value to a two-byte integer?
I just use the OneWire library, it only takes a few lines of code to read the sensor. I also like to work in the integer domain to avoid the code size and run time overhead of floating point.
#include <OneWire.h> //http://www.pjrc.com/teensy/td_libs_OneWire.html
#include <Streaming.h> //http://arduiniana.org/libraries/streaming/
const int DS_PIN = 5; //DS18B20 temperature sensor
OneWire ds(DS_PIN);
void setup(void)
{
Serial.begin(115200);
}
void loop(void)
{
dsStart();
delay(1000); //wait for temperature conversion to complete
int C = dsReadC16();
int F = dsReadF10();
Serial << (C + 8) / 16 << "C " << (F + 5) / 10 << "F\n";
// float C = dsReadC16() / 16.0;
// float F = dsReadF10() / 10.0;
// Serial << C << "C " << F << "F\n";
}
//start temperature conversion
void dsStart(void)
{
ds.reset();
ds.skip();
ds.write(0x44);
}
//get temperature as °C times 16
int dsReadC16(void)
{
uint8_t dsData[9];
ds.reset();
ds.skip();
ds.write(0xBE); //read scratchpad
for ( int i=0; i<9; i++) { //read 9 bytes
dsData[i] = ds.read();
}
if (OneWire::crc8(dsData, 8) == dsData[8]) {
return (dsData[1] << 8) + dsData[0];
}
else {
return -9999; //CRC error
}
}
//get temperature as °F * 10
int dsReadF10(void)
{
long tC16 = dsReadC16(); //°C * 16
if (tC16 == -9999) return tC16;
long tF160 = tC16 * 18; //°F * 160 but without the 32 degree offset
int tF10 = tF160 / 16; //°F * 10
if (tF160 & 15 >= 8) tF10++; //round up to the next tenth if needed (x & 15 is more efficient than x % 16)
tF10 = tF10 + 320; //add in the offset (*10)
return tF10;
}