Spine
Well-Known Member
Hello Everyone,
I finally managed to get my Arduino talking to a DS1624 Digital Thermometer and Memory IC that I had lying around for a while and thought it might be useful to use for homebrewing. Two wire devices typically only have 4 wires going to them (power, ground and 2 communications lines) and can be installed on a bus and individually addressed. All of the a/d conversion is done on the chip and then the information is transmitted digitally back to the Arduino. Think of it as a mini network connected to the Arduino. The benefits of reading temperatures this way are that you don't need to use any analog ports and you can hook up more than one to the "network" (in the case of the DS1624, there can be a maximum of 8 per "network"). Also there is no chance of any further errors being introduced by wiring lengths or and A-D errors that you might encounter using devices such as the LM34 or LM35.
The DS1624 can measure from -55 C to 125 C in increments of 0.03125 C and has a typical error of less than 0.2 C from 0-80C which makes it pretty good for measuring mash temperatures.
The only trick is getting the the SMBUS communications working correctly on the Arduino using the wire library. I have included some sample code below that will read temperatures from the DS1624.
Note: the DS1624 also has 256 bytes of eeprom onboard as well that can be used to store anything you want (such as 128 temperature readings) although I am not using this feature.
The only downside to these devices is the price. On Digikey they are listed for around $5.90 each (CAD) and thats almost double the cost for an LM35.
Note: attached code uses the printfloat library to be able to print floats to the serial port for monitoring. Once downloaded monitor the serial port to get the temperature output. Also the address is defined by a combination of the device address and the address lines. For my example, the first 4 bits are hard coded in the chip and the last 3 are selectable by address lines. I have tied A0-A1-A2 all to Vdd to give a total address of 1001111
I finally managed to get my Arduino talking to a DS1624 Digital Thermometer and Memory IC that I had lying around for a while and thought it might be useful to use for homebrewing. Two wire devices typically only have 4 wires going to them (power, ground and 2 communications lines) and can be installed on a bus and individually addressed. All of the a/d conversion is done on the chip and then the information is transmitted digitally back to the Arduino. Think of it as a mini network connected to the Arduino. The benefits of reading temperatures this way are that you don't need to use any analog ports and you can hook up more than one to the "network" (in the case of the DS1624, there can be a maximum of 8 per "network"). Also there is no chance of any further errors being introduced by wiring lengths or and A-D errors that you might encounter using devices such as the LM34 or LM35.
The DS1624 can measure from -55 C to 125 C in increments of 0.03125 C and has a typical error of less than 0.2 C from 0-80C which makes it pretty good for measuring mash temperatures.
The only trick is getting the the SMBUS communications working correctly on the Arduino using the wire library. I have included some sample code below that will read temperatures from the DS1624.
Note: the DS1624 also has 256 bytes of eeprom onboard as well that can be used to store anything you want (such as 128 temperature readings) although I am not using this feature.
The only downside to these devices is the price. On Digikey they are listed for around $5.90 each (CAD) and thats almost double the cost for an LM35.
Note: attached code uses the printfloat library to be able to print floats to the serial port for monitoring. Once downloaded monitor the serial port to get the temperature output. Also the address is defined by a combination of the device address and the address lines. For my example, the first 4 bits are hard coded in the chip and the last 3 are selectable by address lines. I have tied A0-A1-A2 all to Vdd to give a total address of 1001111
Code:
#include <Wire.h>
#define DS1624_ADDRESS 0x4F
int tempmsb = 0;
int templsb = 0;
int temp2 = 0;
float temperature = 0;
void setup()
{
Serial.begin(9600);
Wire.begin();
delay(100);
ds1624_config();
delay(100);
ds1624_startconvert();
delay(1000);
}
void ds1624_config()
{
// START CONDITION + ADDRESS + MODE
Wire.beginTransmission(DS1624_ADDRESS);
// SEND ACCESS CONFIG PROTOCOL
Wire.send(0xAC);
// SEND CONTINUOUS CONVERSION COMMAND
Wire.send(0x00);
// STOP CONDITION
Wire.endTransmission();
}
void ds1624_startconvert()
{
// START CONDITION + ADDRESS + MODE
Wire.beginTransmission(DS1624_ADDRESS);
// SEND CONTINUOUS CONVERSION COMMAND
Wire.send(0xEE);
// STOP CONDITION
Wire.endTransmission();
}
void ds1624_readtemp()
{
// START CONDITION + ADDRESS + MODE
Wire.beginTransmission(DS1624_ADDRESS);
// SEND READ TEMP COMMAND
Wire.send(0xAA);
// GET THE TEMP MSB AND LSB
Wire.requestFrom(DS1624_ADDRESS, 2);
if (Wire.available()) {
tempmsb = Wire.receive();
}
if (Wire.available()) {
templsb = Wire.receive();
}
temp2 = templsb >> 3;
temperature = (float(tempmsb) + (float(temp2) * 0.03125));
// STOP CONDITION
Wire.endTransmission();
}
void printFloat(float value, int places) {
// this is used to cast digits
int digit;
float tens = 0.1;
int tenscount = 0;
int i;
float tempfloat = value;
// make sure we round properly. this could use pow from <math.h>, but doesn't seem worth the import
// if this rounding step isn't here, the value 54.321 prints as 54.3209
// calculate rounding term d: 0.5/pow(10,places)
float d = 0.5;
if (value < 0)
d *= -1.0;
// divide by ten for each decimal place
for (i = 0; i < places; i++)
d/= 10.0;
// this small addition, combined with truncation will round our values properly
tempfloat += d;
// first get value tens to be the large power of ten less than value
// tenscount isn't necessary but it would be useful if you wanted to know after this how many chars the number will take
if (value < 0)
tempfloat *= -1.0;
while ((tens * 10.0) <= tempfloat) {
tens *= 10.0;
tenscount += 1;
}
// write out the negative if needed
if (value < 0)
Serial.print('-');
if (tenscount == 0)
Serial.print(0, DEC);
for (i=0; i< tenscount; i++) {
digit = (int) (tempfloat/tens);
Serial.print(digit, DEC);
tempfloat = tempfloat - ((float)digit * tens);
tens /= 10.0;
}
// if no places after decimal, stop now and return
if (places <= 0)
return;
// otherwise, write the point and continue on
Serial.print('.');
// now write out each decimal place by shifting digits one by one into the ones place and writing the truncated value
for (i = 0; i < places; i++) {
tempfloat *= 10.0;
digit = (int) tempfloat;
Serial.print(digit,DEC);
// once written, subtract off that digit
tempfloat = tempfloat - (float) digit;
}
}
void loop()
{
ds1624_readtemp();
Serial.print(" Temperature (deg C): ");
printFloat(temperature , 3);
Serial.println();
delay(1000);
}