Arduino with 2wire/SMBUS digital thermometer

Homebrew Talk - Beer, Wine, Mead, & Cider Brewing Discussion Forum

Help Support Homebrew Talk - Beer, Wine, Mead, & Cider Brewing Discussion Forum:

This site may earn a commission from merchant affiliate links, including eBay, Amazon, and others.

Spine

Well-Known Member
Joined
Jul 4, 2008
Messages
75
Reaction score
0
Location
Guelph, ON, CANADA
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

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);

}
 
Hi Derrin,

The DS1624 comes in an 8-pin SOIC (208mil) and 8-pin DIP 9300mil) your choice!

I also have a DS1629 that is also 8pin SOIC that is similar to the DS1624 except it is a real time clock and digital thermometer. I will try to get this one talking on my SMBUS as well tonight. I was planning on putting these inside some tubing sections to make submersible temperature probes, similar to what people have done with the LM34/LM35s.

I am also working on a program for my arduino to control two electric heating elements (4500W), one for BK and one for HLT using the PWM capabilities of the arduino. If my research is correct, the SSRs can be driven directly off the output pins as they can drive up to 40ma. The SSRs I have will accept 3-32vdc input as a trigger!
 
Yea, I've been playing around with the DS18B20 for a few weeks now, and they are really amazing. You can get them for about 3-4bux shipped (US), so it's not too bad, at least compared to a dedicated thermometer.

Also networking multiple sensors is awesome!

Edit: If you haven't already, you may want to check out this link: http://groups.homebrewtalk.com/Open_Source_Mash_Computer.
 
Yea, I've been playing around with the DS18B20 for a few weeks now, and they are really amazing. You can get them for about 3-4bux shipped (US), so it's not too bad, at least compared to a dedicated thermometer.

Also networking multiple sensors is awesome!

Edit: If you haven't already, you may want to check out this link: HomeBrewTalk Groups - Open Source Mash Computer.


I thought that was the one in the SOIC package. Check out the brewtroller group here, they also started a website: BrewTroller
 
Ok, just finished playing around with the DS1629. The schematics call for a 32khz oscillator but I have found this is only required if you are going to be using the clock functions. The temperature functionality works fine without anything attached to the IC. The only problem with the DS1629 is that it can only output the temperature in 0.5 degrees celsius steps which might not be accurate enough for some people. I think the DS1624 is a better option as it has a higher resolution (0.03125 degrees C).
 
yeah I've been interested in the group mentioned, I'm going to buy the sanguino, its the same codebase as the arduino but more powerful. The only problem now is they're all out of them at both places that sell them :p At any rate, I'm still getting all my other parts together anyway, so I'll not have all the hardware. I just built my brew stand, its super half assed ;) I'm not a welder, but I tried and partly succeeded. I'm going to post some pics today sometime. I think real welders and building types will get a good laugh. The important part, though, is that it works :)
 
uhhh help anyone?

... got 4 wires going into the ds1624... connected the sda and scl of the ds1624 to the sda and scl of the arduino.. tried spines code and am only reading "0.00"'s on the serial port monitor in arduino environment.

SPINE, where you at dude?
 
The only problem with the DS1629 is that it can only output the temperature in 0.5 degrees celsius steps which might not be accurate enough for some people. I think the DS1624 is a better option as it has a higher resolution (0.03125 degrees C).

My feeble mind is a bit puzzled. What does resolution mean in relationship to accuracy, and why is it important if the accuracy is the same?
 
Why are you guys going for Anduino boards when you can buy a Brewtroller which is Sanguino based and is already set up for controlling heaters for 3 vessels with PID control, has 14 Pump/Valve outputs, input for 3 Motorola pressure sensors for volume measurements and 4 one wire bus temperature sensors? They are even going to offer a dedicated relay card (14 relays) shortly for pump and valve control. All the hardware is done already and their software is public domain. Why re-invent the wheel. They sell it as a PCB only, Kit or assembled


dsc_0005.jpg


fetch.php


attachment.php
 
My feeble mind is a bit puzzled. What does resolution mean in relationship to accuracy, and why is it important if the accuracy is the same?

I might have said it the wrong way, but essentially the one transmitter has a lower resolution and can only output in 0.5 degree increments, so you will only see temperatures of 55.5, 56, 56.5 etc. I was thinking that 1 degree C is almost 2 degrees F so to me this wouldn't be good enough to measure mash temperatures. The other transmitter has a much higher resolution so it will output in finer steps buy you are correct in the fact that the accuracy might not match the resolution and that much resolution might be meaningless. I don't have the data sheet with me but I seem to remember that these have an accuracy of less than 0.5 degrees F.
 
uhhh help anyone?

... got 4 wires going into the ds1624... connected the sda and scl of the ds1624 to the sda and scl of the arduino.. tried spines code and am only reading "0.00"'s on the serial port monitor in arduino environment.

SPINE, where you at dude?

Sorry for the delay in replying! I have been extremely busy with work due to the end of year crunch in which everyone seems to expect miracles.

I don't have my arduino in front of me right now (and actually I am converting my brewery to 100% PLC setup as I was able to get some transmitters and an old A-B SLC 5/03 and a small panelview for free!) but here are some very important things to check with your circuit.

1. Pinmode should not be set in your code for SDA and SCL lines. The WIRE.H library takes care of all the port configuration and setup of the i2c port.

2. Make sure you are powering the DS1624 and providing a ground.

3. The DS1624 needs to have an address configured. The concept of I2C is kind of like a small network, with all the devices connected to the SDA and SCL lines, so each devices needs to have an address in which you can use to communicate with the device. The DS1624 has half of the address already pre-configured in the chip and you cannot change it. The other Half must be set by connecting the A0,A1,A2 lines to either ground or Vdd. on mine I connected them to Vdd so if you want to use the same code, make sure to do the same.

4. The most important thing that most people forget, is that the ardunio needs to have pull-up resistors on the SDA and SCL lines. Just use 4.7k resistors between the SDA and SCL lines to +5v and it will work ok. The DS1624 chip signals by pulling down the line temporarily but the arduino I think has these floating (not pulled down or up) because they also can use these ports as analog inputs so you need to add this little bit of circuitry yourself.

5. Some 2 wire devices like the DS1624 need to be configured to operate in a certain mode so I found that I would need to de-power and re-power the arduino when I made changes to my code to allow the DS1624 to get reinitiailized on power up.. Simply re-downloading wasn't enough because it seems that the power to the DS1624 never got reset.

Hopefully these tips help you out. I have a feeling it is somewhere in the wiring that you made a mistake. Once you get it working it is very easy to add other devices onto your i2c network!

Good luck!
 
Back
Top