Hi,
I am trying to use my EtherDue with an SPI thermocouple (MAX31855) which is read only, using SCK, MISO and Pin 53 as _CS. On it's own, this works great!
I am trying to write the data from the thermocouple to a microSD. The microSD uses Pin 4 as _CS. Again, on it's own this works great, I can read and write to the card.
When I try to use them together, the SD initialises, but when I try to read the thermocouple, the data seems to get stomped all over?????
Help!
SPI Help
-
- Freetronics Staff
- Posts:853
- Joined:Tue Apr 09, 2013 11:19 pm
- Location:Melbourne, Australia
- Contact:
Re: SPI Help
Hi ghare,
The most likely cause here, as you probably guessed, is one of the CS lines not de-asserting (being driven high) when talking to the other device.
Can you please post the sketch that you are using? (Use the
The most likely cause here, as you probably guessed, is one of the CS lines not de-asserting (being driven high) when talking to the other device.
Can you please post the sketch that you are using? (Use the
Code: Select all
tags to format it correctly). Also if you're not already using it I suggest updating to Arduino 1.5.6, the earlier versions had some problems with multiple SPI devices on Due (I saw it with Ethernet & SD concurrently, but it could have also been a problem with other combinations).
Does the SD card work properly if you take the thermocouple out of the equation?
Regards,
Angus
Re: SPI Help
Angus,
I am already using 1.5.6-r2.
Here is the SD code (just the standard example) However, I did note that if I transposed the SD and SPI header includes, the code breaks. i.e. card doesn't initialise.
Here is the code for the thermocouple interface...
On there own, both of the above work fine.
The following code is the logger I'm writing
The code runs fine, but the first byte being read from the MAX31855 is getting corrupted, resulting in temperature of 1000+ degrees instead of 20ish degrees.
The SD card is being written to and the file reads fine, it just contains the wrong temp??
Cheers,
George
I am already using 1.5.6-r2.
Here is the SD code (just the standard example) However, I did note that if I transposed the SD and SPI header includes, the code breaks. i.e. card doesn't initialise.
Code: Select all
/*
SD card datalogger
This example shows how to log data from three analog sensors
to an SD card using the SD library.
The circuit:
* analog sensors on analog ins 0, 1, and 2
* SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4
created 24 Nov 2010
modified 9 Apr 2012
by Tom Igoe
This example code is in the public domain.
*/
#include <SD.h>
#include <SPI.h>
// On the Ethernet Shield, CS is pin 4. Note that even if it's not
// used as the CS pin, the hardware CS pin (10 on most Arduino boards,
// 53 on the Mega) must be left as an output or the SD library
// functions will not work.
const int chipSelect = 4;
void setup()
{
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
Serial.print("Initializing SD card...");
// make sure that the default chip select pin is set to
// output, even if you don't use it:
pinMode(4, OUTPUT);
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
// don't do anything more:
return;
}
Serial.println("card initialized.");
}
void loop()
{
// make a string for assembling the data to log:
String dataString = "";
// read three sensors and append to the string:
for (int analogPin = 0; analogPin < 3; analogPin++) {
int sensor = analogRead(analogPin);
dataString += String(sensor);
if (analogPin < 2) {
dataString += ",";
}
}
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
File dataFile = SD.open("datalog.txt", FILE_WRITE);
// if the file is available, write to it:
if (dataFile) {
dataFile.println(dataString);
dataFile.close();
// print to the serial port too:
Serial.println(dataString);
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening datalog.txt");
}
}
Code: Select all
/* MAX31855 Thermocouple Interface for Extruder temperature control */
#include <SPI.h>
const unsigned int error = 0x0001; // LSB - Error indicator
const unsigned int sign = 0x8000; // MSB - Sign bit of temperature
const unsigned int temp = 0x7FFC; // 14 bit temperature mask
const int _CS = 53;
void setup()
{
Serial.begin(9600); // Start the serial channel for debugging
SPI.begin(_CS); // Start the SPI channel to talk to MAX31855
pinMode(_CS, OUTPUT); // Setup the _CS pin for the MAX31855 as an output
}
void loop()
{
getTemp();
delay(1000);
}
void getTemp()
{
unsigned int result = readMAX(); // read raw data from MAX31855
if((result & error) == error)
Serial.println("Error with sensor");
else
{
Serial.print("Temp [C] = ");
Serial.println((float) ((result & temp) >> 2)/4, 2);
}
}
unsigned int readMAX()
{
unsigned int result = 0; // result to return
digitalWrite(_CS, LOW); // Pull _CS Low to enable MAX31855
result = SPI.transfer(0x00) << 8; // Send an 0x00 and read result back
result = result | SPI.transfer(0x00);
digitalWrite(_CS, HIGH); // Pull _CS High to disable MAX31855
return(result);
}
The following code is the logger I'm writing
Code: Select all
/* MAX31855 Thermocouple Interface for Extruder temperature control
MISO : D12
SCK : D13
_csTC : D4
*/
#include <SD.h>
#include <SPI.h>
const unsigned int error = 0x0001; // LSB - Error indicator
const unsigned int sign = 0x8000; // MSB - Sign bit of temperature
const unsigned int temp = 0x7FFC; // 14 bit temperature mask
const int _csTC = 53;
const int csSD = 4;
void setup()
{
Serial.begin(9600); // Start the serial channel for debugging
pinMode(csSD, OUTPUT);
pinMode(_csTC, OUTPUT); // Setup the _csTC pin for the MAX31855 as an output
Serial.print("Initializing SD card...");
// make sure that the default chip select pin is set to
// output, even if you don't use it:
// see if the card is present and can be initialized:
if (!SD.begin(csSD)) {
Serial.println("Card failed, or not present");
// don't do anything more:
return;
}
Serial.println("card initialized.");
SPI.begin(_csTC); // Start the SPI channel to talk to MAX31855
}
void loop()
{
// make a string for assembling the data to log:
String dataString = "";
dataString += String(getTemp());
File dataFile = SD.open("PID.log", FILE_WRITE);
// if the file is available, write to it:
if (dataFile) {
dataFile.println(dataString);
dataFile.close();
// print to the serial port too:
Serial.println(dataString);
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening PID.log");
}
delay(1000);
}
float getTemp()
{
unsigned int result = readMAX(); // read raw data from MAX31855
if((result & error) == error)
Serial.println("Error with sensor");
else
{
Serial.print("Temp [C] = ");
Serial.println((float) ((result & temp) >> 2)/4, 2);
return (float) ((result & temp) >> 2)/4;
}
}
unsigned int readMAX()
{
unsigned int result = 0; // result to return
digitalWrite(_csTC, LOW); // Pull _csTC Low to enable MAX31855
result = SPI.transfer(0x00) << 8; // Send an 0x00 and read result back
result = result | SPI.transfer(0x00);
digitalWrite(_csTC, HIGH); // Pull _csTC High to disable MAX31855
return(result);
}
The SD card is being written to and the file reads fine, it just contains the wrong temp??
Cheers,
George
-
- Freetronics Staff
- Posts:853
- Joined:Tue Apr 09, 2013 11:19 pm
- Location:Melbourne, Australia
- Contact:
Re: SPI Help
Hi George,
I think you may need to drive the thermocouple interface CS pin high immediately after you set it as an output:
Because otherwise as an output it's defaulting to low (asserted), and then when you call SD.begin() the MAX31855 is also enabled for the duration of that SD initialisation sequence, which probably causes it to get into a bad state.
- Angus
I think you may need to drive the thermocouple interface CS pin high immediately after you set it as an output:
Code: Select all
pinMode(_csTC, OUTPUT); // Setup the _csTC pin for the MAX31855 as an output
digitalWrite(_csTC, HIGH);
- Angus
Re: SPI Help
Angus,
Tried putting a manual digitalWrite in various places with no luck.
However I have solved the problem in a really UGLY way. I have created a 'throw-away' variable and do an additional SPI transfer before I assert my TC chip select line low. Seems to clear the corrupt data and I get my 2 bytes of temperature data.
I think the problem is probably somewhere in the backend of the SD code. I've noticed there is no SD.end function along the lines of the SPI.end but I don't have time at the moment to delve into the code to find it. My fix will work for getting the data I need to finish my Master's.
Cheers,
George
Tried putting a manual digitalWrite in various places with no luck.
However I have solved the problem in a really UGLY way. I have created a 'throw-away' variable and do an additional SPI transfer before I assert my TC chip select line low. Seems to clear the corrupt data and I get my 2 bytes of temperature data.
Code: Select all
unsigned int readMAX()
{
unsigned int dummy = 0;
unsigned int result = 0; // result to return
digitalWrite(csSD, HIGH);
dummy = SPI.transfer(0xFF);
digitalWrite(_csTC, LOW); // Pull _csTC Low to enable MAX31855
result = SPI.transfer(0x00) << 8; // Send an 0x00 and read result back
result = result | SPI.transfer(0x00);
digitalWrite(_csTC, HIGH); // Pull _csTC High to disable MAX31855
return(result);
}
Cheers,
George