Go Down

Topic: Fetching 32 bits of Data over SPI on Arduino Due (Read 1 time) previous topic - next topic

rcullan

Bingo.... there is no MOSI for this part above I stated

Normally correct but there is no MOSI for this device it reads out only. Quoting directly from the datasheet "Drive CS low and apply a clock signal at SCK to read the results at SO" The limit of the chip is 5 MHz so I set it at 4 as you can see by the code above.

Nick Gammon

I don't see how the code above addresses the issue. Here is something closer to what you said it needed:

Code: [Select]

#include <SPI.h>

const byte SlavePin1 = 10;

void setup ()
  {
  Serial.begin (115200);
  }  // end of setup

void loop ()
  {
  union
    {
    byte byteResult [4]; 
    unsigned long longResult;
    } temperature;
 
  digitalWrite(SlavePin1, LOW);

  // read all 4 bytes
  for (byte i = 0; i < 4; i++)
    temperature.byteResult [i] = SPI.transfer (0);

  digitalWrite(SlavePin1, HIGH);
 
  Serial.println (temperature.longResult);
  delay(1000);
}   


You said the device returns four bytes once CS is asserted. So, you do  4 x SPI.transfer. Since you don't have anything connected to MOSI then you may as well send zero as anything else. If the endian-ness is the other way around, read into the array in the other order.

rcullan

#12
Feb 23, 2013, 11:28 pm Last Edit: Feb 23, 2013, 11:33 pm by rcullan Reason: 1
Nick,
Thank you for the continued help, and the code snippet. I tried this (with some adding debugging serial printouts) and the for loop dosent seem to be looping.

Here is the serial output:
Starting Program
SPI Variables Established
Deselect MAX318555 Chip
Loop Started
MAX31855 Selected
For Loop #
0

And the exact code I am using
Code: [Select]

#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 byteResult [4];  
   unsigned long longResult;
 } temperature;
 
 digitalWrite(SlavePin1, LOW);
 Serial.println("MAX31855 Selected");

 // read all 4 bytes
 for (byte i = 0; i < 4; i++) {
   Serial.println("For Loop #");
   Serial.println(i);
   temperature.byteResult [i] = SPI.transfer (0);
   Serial.println("Data Transfered ");
   delay(1);
 }

 digitalWrite(SlavePin1, HIGH);
 Serial.println("Deselect MAX318555 Chip");
   Serial.println (temperature.longResult);
 delay(1000);
}  


Also here is the Serial instructions from the data sheet (page 9)
http://www.adafruit.com/datasheets/MAX31855.pdf
I believe I have the serial interface established correctly in the listed parameters above. But I am not an expert.

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.

Nick Gammon


Nick,
Thank you for the continued help, and the code snippet. I tried this (with some adding debugging serial printouts) and the for loop dosent seem to be looping.


I don't see anything in your code which would stop the loop looping. However I have not actually used a Due. Perhaps I should move this thread to the Due section?

rcullan

I think I will make a shorter post over there summarazing what I have learned thus far...

One interesting thing is I modified the code slightly to be used on a MEGA 2560 that I also have and the for loop is working but it just returns a 0 on the output everytime.

In any event I would ask one last question on this. How would the code be modified to read bit by bit from the thermocouple? (I dont even know if this is standard with the SPI library) For example, the 1st bit is the sign of the temperature reading, the next 13 are the temperature over the thermocouple. There is a reserved and fault bit in between, and then the next 12 bits are the chips internal data. The remaining 4 bits are fault detectors.

So really what I am trying to do on a transfer level is read the 1st bit as 0 or 1, negative or positive respectively. Read bits 2-14 into a variable for the thermocouple temperature. Then read bits 17-29 for the chip temperature. There are various examples out in the public domain of how to convert the binary data into digestible temperature data formats. But I cant read the data. Sorry if this is a naive question, but I am trying to learn as much as I can here

Go Up