Help Reading MAX31855 Thermocouple on Arduino Due

Hello all, I am stuck on a problem trying to read the MAX31855 Thermocouple Amplifier from Adafruit.

Product Page:Thermocouple Amplifier MAX31855 breakout board (MAX6675 upgrade) : ID 269 : $14.95 : Adafruit Industries, Unique & fun DIY electronics and kits
Data Sheet: http://www.adafruit.com/datasheets/MAX31855.pdf
(The SPI details are found on page 9 and 10)

The problem is if you look at the Adafruit library, it dosen't use the SPI.h library and rather simulates the SPI transfer using a for loop and a digitalRead() on the slave out pin. The reason for this seems to be the MAX31855 itself. This device has no MOSI function, so it dosent matter what you send it. Basically, you drive (and keep) the chip select pin low for 32 clock cycles to read the data. The 32 bit value returned as an unsigned long should be compatible with the current library. The other things to consider is the chip has a 5MHz max limit, the data is presented on the falling edge from MSB to LSB. I believe I have it setup correctly.

My end goal is to read thermocouple data and log it onto an SD card. So I need to use the hardware SPI to interface with it. I have tested it separately and it works well. I am an engineer by day, and hobbiest by night. So I am not an expert, I appreciate both your patience and your help.

Here is an example of my code. I think it is clear what I am trying to do, but isnt working. Just trying to read the raw binary data out in serial. If i grab the thermocouple and warm it up I should see digits 2 through 14 shifting proving its working.

#include <SPI.h>

int SlavePin1 = 4; //Thermocouple #1

void setup() {
  Serial.begin(9600);
  Serial.println("Starting Program");
  //SPI Setup
  SPI.begin(SlavePin1);                // Setup SPI to use pin 4 as CS.
  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SlavePin1,1);        // Use SPI Mode 1 (CPOL = 0, CPHA = 1)
  SPI.setClockDivider(SlavePin1, 21);  // Set SPI Clock divider to 21.(4MHz)
  Serial.println("SPI Variables Established");
  digitalWrite(SlavePin1, HIGH);   // Deselect MAX31855 chip
  Serial.println("Deselect MAX318555 Chip");
}

void loop() {
  Serial.println("Loop Started");
  union {
    byte byte1;
    byte byte2;
    byte byte3;
    byte byte4;  
    unsigned long longResult;
  } temperature;
  
  digitalWrite(SlavePin1, LOW);
  Serial.println("MAX31855 Selected");

  // read all 4 bytes
  temperature.byte1 = SPI.transfer (SlavePin1, 0xFF, SPI_CONTINUE);
  delay(1);
  Serial.println("Got byte 1");
  temperature.byte2 = SPI.transfer (SlavePin1, 0xFF, SPI_CONTINUE);
  delay(1);
  Serial.println("Got byte 2");
  temperature.byte3 = SPI.transfer (SlavePin1, 0xFF, SPI_CONTINUE);
  delay(1);
  Serial.println("Got byte 3");
  temperature.byte4 = SPI.transfer (SlavePin1, 0xFF);
  delay(1);
  Serial.println("Got byte 4");
  Serial.println (temperature, BIN);
  delay(1000);
}

I am trying to work SPI issues also. On the Due SPI extended page, http://arduino.cc/en/Reference/DueExtendedSPI note this:
"NB : once SPI.begin() is called, the declared pin will not be available as a general purpose I/O pin"

So it would appear that using digitalWrite on the select pin will not work - the SPI.transfer would select on first read, you use SPI_CONTINUE to keep selected correctly and it unselects on final transfer (in theory).

The thermocouple data sheet expects you to write 0xFF to do the read?

What type of data is coming out writing the long to serial?

rcullan:
This device has no MOSI function, so it dosent matter what you send it. Basically, you drive (and keep) the chip select pin low for 32 clock cycles to read the data.

Thats basically what I am trying to do with the 4 bytes I have SPI_CONTINUE on the 1st 3. Your on the same page with me, just dosent seem to work though

I'm also intending on working with this device soon, but haven't got around to it yet.

However, it sounds like you're having problems sending 32 bits of data? Am I correct?

I've recently worked with some 16bit dataframe SPI devices, and to send 16bits of data - I simply kept chip select low and repeated SPI.transfer four times, worked fine.

The first SPI.transfer will give you the first 8 bits, the next SPI.transfer will give you the next 8 bits etc etc. There may be a way to run the SPI hardware directly with a 32bit dataframe by accessing the SPI hardware directly without the library - you'd have to check the SAM's datasheet though.

jtw,
Thanks for the reply. In the meantime I have since solved this problem. If you want to Log a MAX31855 onto an SD Shield using an Arduino (which was my end goal) you cannot use the same clock, and MISO signals for both. That ended up being the cause of all the fuss. You must use an un-used digital pin for a mock clock and a mock MISO pin. The Adafruit MAX31855 library has you establish this in your sketch, its pretty self explanitory.

In my case I needed to read and log 4 seperate thermocouples. I ended up buying a Mega2560 for the extra pins and it works just great. Each slave (SD and thermocouple alike) has a chip select pin and the SD card shield uses the standard MOSI, MISO and SCK signals from the Arduino SPI interface. The only additional pins needed is like I said above a mock clock and a mock MISO pin that you set in your sketch for the Adafruit library.

I dont know if its possible to interface into the secondary SPI interface on the due yet. I have ordered a Mega prototyping shield and a kit of header pins to make a simple connector for both. I will update again when I get around to this.