SPI conflict: MAX31855 and microSD card on Teensy 3.2

Status
Not open for further replies.

odinhg

New member
Hello!

I'm trying to read the temperature off a MAX31855 Thermocouple amplifier and save the data to a text file on a microSD card. I have managed to do both things, one at a time. However, the problems arise when I try to do both in the same sketch.

Here is some info (just ask if I forgot something essential):
  • SD card and MAX31855 shares DI (MISO) and SCK
  • SD card has chip select on PIN 2 (with pull-up resistor) and MAX31855 on PIN 14 (also with pull-up resistor)
  • MAX31855 uses hardware SPI
  • Arduino software version 1.8.10
  • Teensyduino software version 1.48

Schematics:
spi_conflict_sch.jpg

Test code for just reading the MAX31855:
Code:
//MAX31855 Minimal test example
#include <SPI.h>
#include <SD.h>
#include "Adafruit_MAX31855.h"

#define MAX0_CS_PIN 15

Adafruit_MAX31855 tc0(MAX0_CS_PIN);

void setup() {
  //For serial com.
  Serial.begin(9600);
  long unsigned debug_start = millis ();
  while (!Serial && ((millis () - debug_start) <= 5000)); 
  
  //Make sure tc0 is disabled at init
  pinMode(MAX0_CS_PIN, OUTPUT);
  digitalWrite(MAX0_CS_PIN, HIGH);

  //Begin MAX31855 SPI and wait 500 ms
  tc0.begin();
  delay(500);
}

void loop() {
  double c = tc0.readCelsius();
  if(isnan(c)){
    Serial.print("MAX31855 error code: ");
    Serial.println(tc0.readError());
  }else{
    Serial.print("Temperature is "); 
    Serial.println(c);
  }
  delay(500);
}
Tested and working. Serial output:
Code:
Temperature is 27.50
Temperature is 27.50
Temperature is 27.50
Temperature is 27.75
Temperature is 27.75
Temperature is 27.50
...


Test code for just writing (and reading) to the SD card:
Code:
//SD Card Write/Read minimal test example
#include <SPI.h>
#include <SD.h>
#include "Adafruit_MAX31855.h"

#define SD_CS_PIN 2

File myFile;

void setup(){
  //For serial com.
  Serial.begin(9600);
  long unsigned debug_start = millis ();
  while (!Serial && ((millis () - debug_start) <= 5000));  

  //Disable SD card before init
  pinMode(SD_CS_PIN, OUTPUT);
  digitalWrite(SD_CS_PIN, HIGH);

  //Initialize SD card
  Serial.print("Initializing SD card...");
  if(!SD.begin(SD_CS_PIN)){
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

  delay(500);
}

void loop(){
  //Open and write to file
  myFile = SD.open("a.txt", FILE_WRITE);
  if(myFile){
    Serial.print("Writing to file...");
    myFile.println("SD card is working!");
    myFile.close();
    Serial.println("OK.");
  }else{
    Serial.println("Error opening file!");
  }
  
  delay(500);

  //Open and read from file
  myFile = SD.open("a.txt");
  if (myFile){
    Serial.println("File content:");
    while (myFile.available()) {
      Serial.write(myFile.read());
    }
    myFile.close();
  }else{
    Serial.println("Error opening file!");
  }
  delay(2000);
}

Tested and working. Serial output:
Code:
Initializing SD card...initialization done.
Writing to file...OK.
File content:
SD card is working!
Writing to file...OK.
File content:
SD card is working!
SD card is working!
Writing to file...OK.
File content:
SD card is working!
SD card is working!
SD card is working!
...

So, now I want to combine these into the same sketch. The following sketch should read the temperature and print it in the serial output, then write a string to a text file on the SD card.

Code:
Code:
//MAX31855 read + SD card write
#include <SPI.h>
#include <SD.h>
#include "Adafruit_MAX31855.h"

#define MAX0_CS_PIN 15
#define SD_CS_PIN 2

File myFile;

Adafruit_MAX31855 tc0(MAX0_CS_PIN);

void setup() {
  //For serial com.
  Serial.begin(9600);
  long unsigned debug_start = millis ();
  while (!Serial && ((millis () - debug_start) <= 5000)); 
  
  //Disable SD card before init
  pinMode(SD_CS_PIN, OUTPUT);
  digitalWrite(SD_CS_PIN, HIGH);
  
  //Initialize SD card
  Serial.print("Initializing SD card...");
  if(!SD.begin(SD_CS_PIN)){
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
  
  //Make sure tc0 is disabled at init
  pinMode(MAX0_CS_PIN, OUTPUT);
  digitalWrite(MAX0_CS_PIN, HIGH);

  //Begin MAX31855 SPI and wait 500 ms
  tc0.begin();
  delay(500);
}

void loop() {
  //Read MAX31855
  double c = tc0.readCelsius();
  if(isnan(c)){
    Serial.print("MAX31855 error code: ");
    Serial.println(tc0.readError());
  }else{
    Serial.print("Temperature is "); 
    Serial.println(c);
  }
  
  delay(500);
  
  //Open and write to file
  myFile = SD.open("a.txt", FILE_WRITE);
  if(myFile){
    Serial.print("Writing to file...");
    myFile.println("SD card is working!");
    myFile.close();
    Serial.println("OK.");
  }else{
    Serial.println("Error opening file!");
  }
  delay(1000);
}

First, I run it without the SD card inserted. Initialization of the SD card fails as expected, and the temperature reading works fine.
Output:
Code:
Initializing SD card...initialization failed!
Temperature is 26.00
Error opening file!
Temperature is 25.75
Error opening file!
Temperature is 26.00
Error opening file!
Temperature is 26.00
Error opening file!
...

Now, if I run it with the SD card present, it initializes fine and writes to the text file. However, the temperature reading is completely wrong! (It does however change when I touch the thermocouple with my fingers.)
Code:
Initializing SD card...initialization done.
Temperature is -2021.25
Writing to file...OK.
Temperature is -2021.50
Writing to file...OK.
Temperature is -2021.25
Writing to file...OK.
Temperature is -2021.25
Writing to file...OK.
Temperature is -2021.25
Writing to file...OK.
...

I could do a dirty fix and just add some constant (+2049 looks about right) to the temperature reading to get the following output:
Code:
Initializing SD card...initialization done.
Temperature is 27.50
Writing to file...OK.
Temperature is 27.75
Writing to file...OK.
Temperature is 27.75
Writing to file...OK.
...

But that isn't very satisfying..

So it looks like the SD card SPI communication is interfering with the MAX31855 library in some way.

Does anyone have any idea what the cause might be? And any suggestions for troubleshooting or fixing this problem?
 
I found a fix which seems to be working pretty well. In Adafruit_MAX31855.cpp and Sd2Card.cpp I changed the maximum SPI clock speed to 500000 (from 4000000). This is fast enough for my application.
Code:
SPISettings(500000, MSBFIRST, SPI_MODE0)

Once in a while, the thermocouple reads -2021 degrees C. (Maybe once per 200 readings approximately). However, I'll just ignore such absurd values.
 
Status
Not open for further replies.
Back
Top