Bad readings with K Thermocouple+MAX31855+Arduino Mega

Hi all!!!, I´m trying to use a K type thermocouple with an arduino Mega...For this I get a MAX31855 microchip for analogic-digital conversion and using SPI (not the module, only the chip). I'm using an Arduino Mega 1280, but I only get bad measurements (I tried different libraries in arduino 1.01 and Arduino 0023)....This is an example what I get (I heat the probe with my hand, and when I get bad measurements I stopped)-I think that it is clear:

And the connection diagram I'm using is:

I think that the error is in my connections, not in code....But if anyone can help me, Ill be pleased-I´m about a month trying to solve this....Thank you for your interest. :slight_smile:

"I think that the error is in my connections, not in code"

It'd be easier to help if you posted both.

Datasheet

"The Typical Application Circuit shows the device interfaced
with a microcontroller. In this example, the device
processes the reading from the thermocouple and
transmits the data through a serial interface. Drive CS
low and apply a clock signal at SCK to read the results
at SO. Conversions are always being performed in the
background. The fault and temperature data are only be
updated when CS is high.
Drive CS low to output the first bit on the SO pin. A
complete serial-interface read of the cold-junction compensated
thermocouple temperature requires 14 clock
cycles. Thirty-two clock cycles are required to read both
the thermocouple and reference junction temperatures
(Table 2 and Table 3.) The first bit, D31, is the thermocouple
temperature sign bit, and is presented to the SO
pin within tDV of the falling edge of CS. Bits D[30:18]
contain the converted temperature in the order of MSB
to LSB, and are presented to the SO pin within tD0 of the
falling edge of SCK. Bit D16 is normally low and goes
high when the thermocouple input is open or shorted to
GND or VCC. The reference junction temperature data
begins with D15. CS can be taken high at any point while
clocking out conversion data. If T+ and T- are unconnected,
the thermocouple temperature sign bit (D31) is
0, and the remainder of the thermocouple temperature
value (D[30:18]) is 1."

All the examples would require 4 SPI transfers, after which you'd mask off for the 14 bits of interest.

Thank you CrossRoads for your fast answer....I tried different codes with the same problem. An example of one of this(the code used in the capture of the monitor I posted before), is:

#include <max31855.h>

// ***** PIN ASSIGNMENT *****
int thermocoupleSO = 50;
int thermocoupleCS = 53;
int thermocoupleCLK = 52;

double inputC;
double inputF;
double inCJC;
int inFault;

bool inOpen=0;
bool inShortGND=0;
bool inShortVCC=0;
bool inFaulted;

// Seconds timer
int timerSeconds;
unsigned long nextCheck;

// Specify MAX31855 thermocouple interface
MAX31855 thermocouple(thermocoupleCLK, thermocoupleCS, thermocoupleSO);

void setup()
{

// Serial communication at 57600 bps
Serial.begin(57600);
}

void loop()
{

inputC = thermocouple.readCelsius();
inputF = thermocouple.readFarenheit();
inCJC = thermocouple.readCJC();
inFault = thermocouple.readFaultCode();

// alternative method
// inFaulted = thermocouple.readMAX31855( &inputC, &inCJC, &inOpen, &inShortGND, &inShortVCC);

// Send temperature and time stamp to serial
Serial.print("Temperature: ");
Serial.print(inputC);
Serial.print("C, ");
Serial.print(inputF);
Serial.print("F. CJC: ");
Serial.print(inCJC);
Serial.print("C ");
if (inFault)
Serial.println("Faulted");
else
Serial.println(" No Fault");

delay(1000);

}

The connections are like I posted in the diagram, I don´t understand you well.....If it´s neccesary, I will make photographs of the circuit and the Arduino, and I'll post it here. Thank you for your help :slight_smile:

CrossRoads:
"The Typical Application Circuit shows the device interfaced
with a microcontroller. In this example, the device
processes the reading from the thermocouple and
transmits the data through a serial interface. Drive CS
low and apply a clock signal at SCK to read the results
at SO. Conversions are always being performed in the
background. The fault and temperature data are only be
updated when CS is high.
Drive CS low to output the first bit on the SO pin. A
complete serial-interface read of the cold-junction compensated
thermocouple temperature requires 14 clock
cycles. Thirty-two clock cycles are required to read both
the thermocouple and reference junction temperatures
(Table 2 and Table 3.) The first bit, D31, is the thermocouple
temperature sign bit, and is presented to the SO
pin within tDV of the falling edge of CS. Bits D[30:18]
contain the converted temperature in the order of MSB
to LSB, and are presented to the SO pin within tD0 of the
falling edge of SCK. Bit D16 is normally low and goes
high when the thermocouple input is open or shorted to
GND or VCC. The reference junction temperature data
begins with D15. CS can be taken high at any point while
clocking out conversion data. If T+ and T- are unconnected,
the thermocouple temperature sign bit (D31) is
0, and the remainder of the thermocouple temperature
value (D[30:18]) is 1."

All the examples would require 4 SPI transfers, after which you'd mask off for the 14 bits of interest.

Thank you for your help and interest CrossRoads, this is an interesting information about the running of this chip, but I don´t know how to apply this in my problem...Sorry for my ignorance, and thank you

I am not familiar with the library max31855.h
As such, I would simply do this:

digitalWrite(ssPin, LOW);
byte3 = SPI.transfer(0);
byte2 = SPI.transfer(0);
byte1 = SPI.transfer(0);
byte0 = SPI.transfer(0);
digitalWrite(ssPin, HIGH);

dataResult = (byte3 <<24) + (byte2 <<16) +(byte1<<8 ) +byte0; // unsigned long

14bitTemp = dataResult >>18; // shift off the non-temperature bits

and do the math on the 14 bits that matter:

"For a K-type thermocouple, the voltage changes by about 41FV/NC, which approximates
the thermocouple characteristic with the following linear equation:
VOUT = (41.276FV/NC) x (TR - TAMB)
where VOUT is the thermocouple output voltage (FV), TR is the temperature of the remote thermocouple junction
(NC), and TAMB is the temperature of the device (NC)."

Or roughly (if I have the units correct):

float kTemp = (41.276/1000000)*14bitTemp;

You can mask for the other bits & check for errors (opens, shorts).

Would be nice to get this chip working, would make a great alternative to

Thermocouple Amplifier AD595-AQ

typically used in oven controllers, as the MAX31855 is available for quite a few dollars less:

and AD595 is only from Arrow.com that I have been able to find:
http://components.arrow.com/part/detail/52071S5444913N2771

or Sparkfun

Thank you for your reply CrossRoads. I tried to do this, but without any result (I´m sure I did something wrong...).I´m sure too that the different codes I tried are correct because they examples from the different libraries for MAX31855. I'm thinking that the error could be for bad connections or bad using of level shifters (I´m using 2 voltage dividers- 1 for CS pin and other for SCK pin), to get 3v3 for the MAX31855. MISO pin is directly to Arduino Mega Digital 50.
There is a detail in the measurements: At ambient temperature (about 14ºC it is measuring 2ºC and when I heat with my hand (view my first post), at more than 31,5ºC, it measurement is 0ºC. When I heat the probe with a lighter, the temperature increases more and more but It has a lot of bad measurements and others with 0ºC........Any suggestions for my circuit or pin configuration?

Are you sure you have the right Kind of thermocouple for the chip you are using?
The MAX31855 has 7 versions:
MAX31855E,J,K,N,R,S,T, to go with the different kinds of probes.
You have a MAX31855K ?

Thank you for your reply...Yes I´m sure, I get the samples from MAXIM-IC and exactly is MAX31855KASA+, I´ve three of these, and everyone have the same problem. They are connected in a SOIC to DIP adapter connected in a protoboard, as you can see in the next photo:

(The capacitor that you can see between red and blue wire is 10nF for reducing noise-I didn´t draw it in the scheme)

The probe is from my multimeter (Velleman DVM 890), and I´m sure that it's a K probe too. I´m very confused :~

I don't know then. You seem to be connected to the right places.

Thank you for your help and replies CrossRoads.....Anyone has any suggestion??? Anyone used MAX31855??I can´t make it to run properlly....Could it be for the solder paste or using a protoboard---making a new couple of metals and giving me wrong results??? :~

hello i recently started using max31855, and i wrote a code based on max31855.h library that seems to be working well, can not give sure because I was wrong when I ordered the samples and it was not for the right sensor. I still am waiting the right max31855.
try the the code below and give me a feedback. It's likely that is not optimized, because I have not had much time to work on it .
If you have any doubts says.

Sorry for my bad english.

#define cs 10
#define sclk 13
#define miso 12

void setup() {
  //define pin modes
  pinMode(cs, OUTPUT);
  pinMode(sclk, OUTPUT); 
  pinMode(miso, INPUT);

  digitalWrite(cs, HIGH);

  Serial.begin(9600);
  
  Serial.println("MAX31855 test");

}

void loop() 
{
  int f = readInternal();
  Serial.print("Internal Temp = ");
  Serial.println(f);
  
  int c = readcelsius();
  
  if (isnan(c)) {
     Serial.println("Something wrong with thermocouple!");
   } 
   else 
   {
     Serial.print("C = "); 
     Serial.println(c);
     //Serial.print("spiread32() = "); 
     //Serial.println(spiread32());
   }
 
   delay(1000);
}

double readInternal() {
  unsigned int v;
  
  v = spiread32();
  
  // ignore bottom 4 bits - they're just thermocouple data
  v >>= 4;

  // pull the bottom 11 bits off
  float internal = v & 0x7FF;
  internal *= 0.0625; // LSB = 0.0625 degrees
  // check sign bit!
  if (v & 0x800) 
    internal *= -1;
  //Serial.print("\tInternal Temp: "); Serial.println(internal);
  return internal;
}

float readcelsius() {

  long v;
  
  v = spiread32();
  
  // get rid of internal temp data, and any fault bits
  v >>= 18;

  // pull the bottom 13 bits off
 short temp = v & 0x3FFF;

  // check sign bit
  if (v & 0x2000) 
    temp |= 0xC000;
  
  float centigrade = v;

  //centigrade *= 0.25;
  return centigrade;
}

long spiread32() { 
  
  long d = 0;

  digitalWrite(sclk, LOW);
  delay(1);
  digitalWrite(cs, LOW);
  delay(1);

  for (int i=31; i>=0; i--)
  {
    digitalWrite(sclk, LOW);
    delay(1);
    d <<= 1;
    if (digitalRead(miso)) 
    {
      d |= 1;
    }

    digitalWrite(sclk, HIGH);
    delay(1);
  }

  digitalWrite(cs, HIGH);
  //Serial.println(d, HEX);
  return d;
}

byte readError() 
{
  return spiread32() & 0x7;
}

@peko86
What is typical is that the output in CJC makes jumps of 8 degrees C

Drop to zero often indicate bad wiring - can also if the breadboard is overused

i am using chip:
M31855K
1746A2
+783AE

internal temp(temp2) is ok but thermocouple(temp1) readings are jumping up/down by 8 degree .. why so?

temp.jpg