DS1631 - Arduino Code and Temperature Validation

I have need for a digital thermometer in many of my projects and thought it would be nice to do a simple validation against a standard thermocouple. I have also provided an Arduino Script for use with the Arduinos IDE. This code comes from the archived Arduino forums; I have updated it so it will work with a newer IDE (version 1.6.6) and Wire.h library.

The thermocouple is read using a NI 9214 thermocouple input module as shown below. The wiring schematic for the DS1631 as tested is also provided. All three address pins are pulled low, to give the chip an address of 0x90.

The figures below are a brief set of data collected during testing of the DS1631. Here the IC is tested against a type J thermocouple. Data in the first figure was collected using a heat gun to heat up both sensors. The heat gun was set to 100 C, and the data was collected at 500 Hz for both sensors. The difference in the recorded temperature may be a factor of how the DS1631 package holds heat, vs the bare tip of the thermocouple. The second set of data was collected over a few hours in my office. You can clearly see the temperature swing at the beginning when I leave my office. The temperature is higher when I am in the office (lights on and door open) and cooler when I leave (lights off and door closed). This second set was recorded at 0.5 Hz. The DS1631 seems to track the thermocouple temperature when the sensors are only measuring the ambient temperature.

DS1631 code for I2C address set to 0x90

#include <Wire.h>

// PIN adresses are set to GND
#define DS1631_ADDR 0x90 >> 1

void setup(){
 // Setup Serial connection
 Serial.println("DS1631 test: Temp. sensor"); 
 Wire.begin();             // join I2C bus

 // Stop conversion to be able to modify "Access Config" Register
 Wire.write((int)(0x22)); // Stop conversion
 // Read "Access Config" regsiter
 Wire.write((int)(0xAC)); // @AC : Acces Config
 Wire.requestFrom(DS1631_ADDR,1); //Read 1 byte
 int AC = Wire.read(); // receive a byte

 Serial.print("Acces Config (Before): "); Serial.print(AC);  Serial.println("");
 // WRITE into "Access Config" Register
 Wire.write(0xAC); // @AC : Acces Config
 Wire.write(0x0C); // Continuous conversion & 12 bits resolution
 // READ "Access Config" register
 Wire.write((int)(0xAC)); // @AC : Acces Config
 AC = Wire.read();

 Serial.print("Acces Config (AFTER): "); Serial.print(AC);  Serial.println("");
 // START conversion to get T°
 Wire.write((int)(0x51)); // Start Conversion

// Main Loop
void loop(){
 //READ T°
 Wire.write((int)(0xAA)); // @AA : Temperature
 Wire.requestFrom(DS1631_ADDR,2); // READ 2 bytes
 Wire.available(); // 1st byte
 int Th = Wire.read(); // receive a byte
 Wire.available(); // 2nd byte
 int Tl = Wire.read(); // receive a byte

 // T° processing
 if(Th>=0x80) //if sign bit is set, then temp is negative
 Th = Th - 256;
 int T_dec=(10*(100*(Tl/16)))/16; // decimal part of the T°

 // Display T° on "Serial Monitor"
 Serial.print("Temperature : ");
 Serial.print(Th);   Serial.print(".");
 if (T_dec<10)   Serial.print("0");
 if (T_dec<100)   Serial.print("0");
 Serial.print(T_dec);   Serial.print(" degC / ");
 Serial.print("Th register: "); Serial.print(Th);  Serial.print(" / ");
 Serial.print("Tl register: "); Serial.print(Tl);  Serial.println("");
 // Wait 1s before restart

A few more pictures can be found on my current website.

At http://adowney2.public.iastate.edu/projects/DS1631/DS1631.html#

Nice graphs.

I have a few notes.

Are you sure the calculation is okay. By using integer calculation, I think some resolution vanishes. I'm not sure it will work for the full temperature range of the DS1631.

In your code, you do this: Wire.available ( ) ;
Please remove those.
The Wire.requestFrom() is a I2C transmission on its own. When the Wire.requestFrom() returns, the I2C transmission has completely finished and the received data is waiting in a buffer in the Wire library. The Wire.read() only reads the data from that buffer.

The DS1631 can operate at 3.3V and 5V. You have a mix between them. There is current flowing into SDA and SCL via the DS1631 to the 3.3V.
For 3.3V : use pullup resistors of 4k7 to 3.3V. Not 10k, because then the SDA and SCL voltage might be too high, due to the internal pullup resistors of the Arduino.
For 5V : use pullup resistors of 4k7 or 10k or whatever to 5V.

Koepel, I swear you follow me on here. :slight_smile:

I pulled the code of the old forums, I really should go through it and clean it up.

I see what you mean for the pull-up resistors on 3.3v. I will have to change that in the schematic for the next person.

I will try and update this post in the next week.