[SD card begin problem] - Please help me

[SD card begin problem] - Please help me.

hello. Thank you for reading my article.

  1. Currently Arduino Mega, 'MAX31865' and 'SD Card' are implemented in circuit.

  2. After receiving the temperature value from 'MAX31865' normally, 'SD card' execution proceeds with 'finishing SPI communication'.

#define SD_CARD 53
#define TEMPERATURE 24

SPI.end(); delay(1); SPI.begin(); delay(1);
digitalWrite(SD_CARD, HIGH);digitalWrite(TEMPERATURE, LOW);
delay(10);
if (SD.begin(SD_CARD)) { Serial.println("SD CARD SUCCESS"); }
else { Serial.println("SD CARD FAIL"); }

It works well at first, but 'SD.begin(SD_CARD)' does not work within about 8 to 24 hours. Why?
Advice and answers, assumptions, etc. please.

That type of SD card adapter commonly has a problem where it does not properly release the MISO line, which will cause problems if there is another device on the SPI bus. It is possible to modify the adapter to work properly, but that requires fairly good soldering skills.

Maybe your RAM ran out?............

@david_2018
Are you referring to the circuit diagram above?
I actually tried it, but it made no difference.

@anon92864395
Maybe your RAM ran out?...........
Q1) Do you know if it is a RAM problem? Is there any way to check?
Q2) Is there a solution?

Hi @myksj,

it is not easy to give an answer without knowing your sketch ...

Could you explain what you mean with

"but 'SD.begin(SD_CARD)' does not work within about 8 to 24 hours."

?

Are you calling SD.begin() in loop() ???

@ec2021

'MAX31865' and 'SD Card' use the same SPI communication line.

If 'SD.begin(SD_CARD)' is executed through the 'SD Card' library, 'MAX31865' temperature value cannot be read.
That is, if 'SD.begin(SD_CARD)' is used, 'MAX31865' cannot be used.

so,

SPI. end(); delay(1); SPI. begin(); delay(1);
digitalWrite(SD_CARD, HIGH); digitalWrite(TEMPERATURE, LOW);
delay(10);
if (SD.begin(SD_CARD)) { Serial.println("SD CARD SUCCESS"); }
else { Serial. println("SD CARD FAIL"); }

You have to redeclare and run it as above to get it to work.

No, that is not the case ... For two or more SPI devices you have to use different Slave Select pins. That's the purpose of the SS pin! (They are nowadays called CS pins).

See here http://www.learningaboutelectronics.com/Articles/Multiple-SPI-devices-to-an-arduino-microcontroller.php

When you initialize the SD Card reader with SD.begin(SD_CARD); the value of SD_CARD equals the corresponding SS pin. You have to connect the MAX31865 to a different pin of your MEGA and use that pin number in the declaration, e.g.:

#define MAX_SS_PIN 10
Adafruit_MAX31865 max = Adafruit_MAX31865(MAX_SS_PIN);

This way both won't collide.

See https://learn.adafruit.com/adafruit-max31865-rtd-pt100-amplifier/arduino-code

If you use SD.begin(SD_CARD) multiple times your controller quite likely finally runs out of memory ...

It is correct that you have to change the CS Pins status if you want to read from the other device but you cannot use SD.begin() several times ...

So what happens if you use SD.begin() in setup and frame your calls of the MAX as follows:

digitalWrite(SD_CARD, HIGH);
digitalWrite(TEMPERATURE,LOW);
// Read the MAX data here ...
// ...
digitalWrite(TEMPERATURE,HIGH);
digitalWrite(SD_CARD, LOW);

LOW selects the device and HIGH deselects it ...

I am starting to think that it is not a RAM problem.
But anyway:
Q1: I have no idea about that. Maybe ask @anon56112670 about that?
Q2: maybe change your serial prints to Serial.println(F(stuff to print));

Please note that I don’t know much about F() .

Do you use String variables, or the keyword "new" to allocate memory, anywhere in the code?

@ec2021
@anon92864395
@david_2018

#include <Adafruit_MAX31865.h>
#include <SD.h>
#include <SPI.h>

#define SD_CARD            53

const byte temp_pin[4] = {22,51,50,52};
Adafruit_MAX31865 thermo = Adafruit_MAX31865(temp_pin[0],temp_pin[1],temp_pin[2],temp_pin[3]);
#define RREF      400.0
#define RNOMINAL  100.0

void setup() {
  
  Serial.begin(115200);
  Serial.println("Adafruit MAX31865 PT100 Sensor Test!");
  thermo.begin(MAX31865_3WIRE);
  pinMode(SD_CARD, OUTPUT); digitalWrite(SD_CARD, LOW);    
  pinMode(temp_pin[0], OUTPUT); digitalWrite(temp_pin[0], LOW); 

  
  if (SD.begin(SD_CARD)) {  Serial.println("SD-INIT SUCCESS");  }
                     else{  Serial.println("SD-INIT FAIL");     }

                     
 
  
}
long numbets = 0;
  
void loop() {

  Serial.println("---------------------------------------------------");
  digitalWrite(temp_pin[0], HIGH);digitalWrite(SD_CARD, LOW);    
  delay(10);  
  uint16_t rtd = thermo.readRTD();
  Serial.print("RTD value: "); Serial.println(rtd);
  float ratio = rtd;
  ratio /= 32768;
  Serial.print("Ratio = "); Serial.println(ratio,8);
  Serial.print("Resistance = "); Serial.println(RREF*ratio,8);
  Serial.print("Temperature = "); Serial.println(thermo.temperature(RNOMINAL, RREF));

  // Check and print any faults
  uint8_t fault = thermo.readFault();
  if (fault) {
    Serial.print("Fault 0x"); Serial.println(fault, HEX);
    if (fault & MAX31865_FAULT_HIGHTHRESH) {
      Serial.println("RTD High Threshold"); 
    }
    if (fault & MAX31865_FAULT_LOWTHRESH) {
      Serial.println("RTD Low Threshold"); 
    }
    if (fault & MAX31865_FAULT_REFINLOW) {
      Serial.println("REFIN- > 0.85 x Bias"); 
    }
    if (fault & MAX31865_FAULT_REFINHIGH) {
      Serial.println("REFIN- < 0.85 x Bias - FORCE- open"); 
    }
    if (fault & MAX31865_FAULT_RTDINLOW) {
      Serial.println("RTDIN- < 0.85 x Bias - FORCE- open"); 
    }
    if (fault & MAX31865_FAULT_OVUV) {
      Serial.println("Under/Over voltage"); 
    }
    thermo.clearFault();
  }
  Serial.println();
  delay(1000);
  Serial.println("---------------------------------------------------");

  
  digitalWrite(temp_pin[0], LOW);digitalWrite(SD_CARD, HIGH);    
  delay(10);  
  numbets++;
  File myFile;
  myFile.flush(); delay(2);
  myFile = SD.open("SOME.txt", FILE_WRITE);
  if (myFile) {    
    String msg = "HELLO TEST-"+String(numbets);
    myFile.println(msg);
    Serial.println(msg);
  }
  delay(10000);  
}

Blockquote

fig

#include <Adafruit_MAX31865.h>
#include <SD.h>
#include <SPI.h>

#define SD_CARD            53

const byte temp_pin[4] = {22,51,50,52};
Adafruit_MAX31865 thermo = Adafruit_MAX31865(temp_pin[0],temp_pin[1],temp_pin[2],temp_pin[3]);
#define RREF      400.0
#define RNOMINAL  100.0

void setup() {
  
  Serial.begin(115200);
  Serial.println("Adafruit MAX31865 PT100 Sensor Test!");
  thermo.begin(MAX31865_3WIRE);
  pinMode(SD_CARD, OUTPUT); digitalWrite(SD_CARD, LOW);    
  pinMode(temp_pin[0], OUTPUT); digitalWrite(temp_pin[0], LOW); 
  
  if (SD.begin(SD_CARD)) {  Serial.println("SD-INIT SUCCESS");  }
                     else{  Serial.println("SD-INIT FAIL");     }
  
}
long numbets = 0;
  
void loop() {

  Serial.println("---------------------------------------------------");
  digitalWrite(temp_pin[0], HIGH);digitalWrite(SD_CARD, LOW);    
  delay(10);  
  
 
  uint16_t rtd = thermo.readRTD();
  Serial.print("RTD value: "); Serial.println(rtd);
  float ratio = rtd;
  ratio /= 32768;
  Serial.print("Ratio = "); Serial.println(ratio,8);
  Serial.print("Resistance = "); Serial.println(RREF*ratio,8);
  Serial.print("Temperature = "); Serial.println(thermo.temperature(RNOMINAL, RREF));

  // Check and print any faults
  uint8_t fault = thermo.readFault();
  if (fault) {
    Serial.print("Fault 0x"); Serial.println(fault, HEX);
    if (fault & MAX31865_FAULT_HIGHTHRESH) {
      Serial.println("RTD High Threshold"); 
    }
    if (fault & MAX31865_FAULT_LOWTHRESH) {
      Serial.println("RTD Low Threshold"); 
    }
    if (fault & MAX31865_FAULT_REFINLOW) {
      Serial.println("REFIN- > 0.85 x Bias"); 
    }
    if (fault & MAX31865_FAULT_REFINHIGH) {
      Serial.println("REFIN- < 0.85 x Bias - FORCE- open"); 
    }
    if (fault & MAX31865_FAULT_RTDINLOW) {
      Serial.println("RTDIN- < 0.85 x Bias - FORCE- open"); 
    }
    if (fault & MAX31865_FAULT_OVUV) {
      Serial.println("Under/Over voltage"); 
    }
    thermo.clearFault();
  }
  Serial.println();
  delay(1000);
  Serial.println("---------------------------------------------------");

  
  digitalWrite(temp_pin[0], LOW);digitalWrite(SD_CARD, HIGH);    
  delay(10);  
  //-----------------------------------------------------------------------------------//  
  SPI.end();  SD.begin(SD_CARD);  delay(1); 
  //-----------------------------------------------------------------------------------//  
  
  numbets++;
  File myFile;
  myFile.flush(); delay(2);
  myFile = SD.open("SOME.txt", FILE_WRITE);
  if (myFile) {    
    String msg = "HELLO TEST-"+String(numbets);
    myFile.println(msg);
    Serial.println(msg);
  }
  delay(10000);
  
}

'begin' needs to be set again to measure the PT-100 temperature.

The problem is that sometimes it gets stuck.

I don't know why.

Why is that? You use that pin for the SD card, so hands off that pin. You open the card with every loop, close it before reopen.

@intstarep

Thank you for leaving an answer.

digitalWrite(SD_CARD, LOW);

The above command is meaningless. Because it proceeds with 'begin' anyway.

digitalWrite(SD_CARD, HIGH);

Even if you proceed to the top, an error occurs,
but it is the same, so I proceeded with LOW.
'HIGH' according to the module used for SPI communication is not a problem. We want to solve a fundamentally different problem.

also,

digitalWrite(SD_CARD, LOW);

The reason for the above command is to perform 'SD card reader' function and 'PT-100 temperature' function through SPI communication.

There is no real need to use String to put all the text into one line.
If you are going to open the file every time though loop(), then you also need to close it.

  File myFile;
  myFile = SD.open("SOME.txt", FILE_WRITE);
  if (myFile) {
    myFile.print("HELLO TEST-");
    myFile.println(numbets);
    Serial.print("HELLO TEST-");
    Serial.println(numbets);
    myFile.close();
  }

The flush() makes no sense, the purpose of flush() is to write the SD buffer to the card, but you do this before you open the file or write anything to the buffer. Even after printing to the SD card, there is no need to use flush() when you are going to close the file, since closing the file writes the buffer to the card.

  File myFile;
  myFile.flush(); delay(2);
  myFile = SD.open("SOME.txt", FILE_WRITE);

I believe intstarep was referring to the libraries for the SD card and the MAX31865 handling the select lines properly, so there is no need for you to be setting the HIGH/LOW state yourself.

@david_2018

Thank you for posting your reply. Everything you wrote is correct.

However, the problem is that the two functions cannot be performed without a separate setting.
In other words, if you use the libraries 'Adafruit_MAX31865.h' and 'SD.h'
Cannot get temperature value.

I have taken your second sketch from post # 10 and made some changes to it. At least from theory ( :wink: ) it should work this way if both libs are working correctly ...

I have made comments where I removed (commented out) or added lines.

Instead of initializing SD every loop() the file will now be opened and closed for each write access.

#include <Adafruit_MAX31865.h>
#include <SD.h>
#include <SPI.h>

#define SD_CARD            53

const byte temp_pin[4] = {22,51,50,52};
Adafruit_MAX31865 thermo = Adafruit_MAX31865(temp_pin[0],temp_pin[1],temp_pin[2],temp_pin[3]);
#define RREF      400.0
#define RNOMINAL  100.0

void setup() {
  
  Serial.begin(115200);
  Serial.println("Adafruit MAX31865 PT100 Sensor Test!");
  thermo.begin(MAX31865_3WIRE);
  // pinMode(SD_CARD, OUTPUT); digitalWrite(SD_CARD, LOW);  // Not required this should be done by the lib
  pinMode(temp_pin[0], OUTPUT); 
  digitalWrite(temp_pin[0], HIGH); // Changed from LOW to HIGH, otherwise the device would be selected
                                   // As this is not the "standard" CS pin it might be ok to prepare it ?!?
                                   // Usually pinMode OUTPUT should set the pin HIGH anyway
  
  if (SD.begin(SD_CARD)) {  Serial.println("SD-INIT SUCCESS");  }
                     else{  Serial.println("SD-INIT FAIL");     }
  
}
long numbets = 0;
  
void loop() {

  Serial.println("---------------------------------------------------");
  //digitalWrite(temp_pin[0], HIGH);digitalWrite(SD_CARD, LOW);    // Not required should be done by the SD lib
  // and wrong at this position as the next access to SPI should be done by the MAX device...
  // delay(10);  
  
 
  uint16_t rtd = thermo.readRTD();
  Serial.print("RTD value: "); Serial.println(rtd);
  float ratio = rtd;
  ratio /= 32768;
  Serial.print("Ratio = "); Serial.println(ratio,8);
  Serial.print("Resistance = "); Serial.println(RREF*ratio,8);
  Serial.print("Temperature = "); Serial.println(thermo.temperature(RNOMINAL, RREF));

  // Check and print any faults
  uint8_t fault = thermo.readFault();
  if (fault) {
    Serial.print("Fault 0x"); Serial.println(fault, HEX);
    if (fault & MAX31865_FAULT_HIGHTHRESH) {
      Serial.println("RTD High Threshold"); 
    }
    if (fault & MAX31865_FAULT_LOWTHRESH) {
      Serial.println("RTD Low Threshold"); 
    }
    if (fault & MAX31865_FAULT_REFINLOW) {
      Serial.println("REFIN- > 0.85 x Bias"); 
    }
    if (fault & MAX31865_FAULT_REFINHIGH) {
      Serial.println("REFIN- < 0.85 x Bias - FORCE- open"); 
    }
    if (fault & MAX31865_FAULT_RTDINLOW) {
      Serial.println("RTDIN- < 0.85 x Bias - FORCE- open"); 
    }
    if (fault & MAX31865_FAULT_OVUV) {
      Serial.println("Under/Over voltage"); 
    }
    thermo.clearFault();
  }
  Serial.println();
  delay(1000);
  Serial.println("---------------------------------------------------");
  
  // digitalWrite(temp_pin[0], LOW);digitalWrite(SD_CARD, HIGH);   // Not required and even
                                                                   //  wrong at this place
                                                                   // as it would select the MAX
                                                                  
  // delay(10);  
  //-----------------------------------------------------------------------------------//  
  // SPI.end();  SD.begin(SD_CARD);  delay(1);   // Not required and possibly cosuming memory with every call
  //-----------------------------------------------------------------------------------//  
  
  numbets++;
  File myFile;
  // myFile.flush(); delay(2); // Not required as the File is not open at this point
  myFile = SD.open("SOME.txt", FILE_WRITE);
  if (myFile) {    
    String msg = "HELLO TEST-"+String(numbets);
    myFile.println(msg);
    Serial.println(msg);
    // Closing of the file 
    // added at this place, just in case that
    // the power is off during operation
    // so that all data are "safe" on SD Card.
    myFile.close();
  }
  delay(10000);
  
}

If you like you may test it and give some feedback ...

Good luck!

IMHO you don't have to assign that pin nor switch it LOW or HIGH. I think thats your issue here. Give it a try without.

@ec2021
@intstarep

  1. Thank you for your reply.

  2. I know about your advice. I know.

  3. However, if you actually use the example source code you gave, you cannot get the temperature value of 'PT-100'. That's the biggest problem.

fig

It feels like two libraries are conflicting.
Because of this, we are proceeding by using the 'digitalWrite' function and 'begin' externally.
Only in this way can the temperature value of 'PT-100' be obtained.

I found this post, maybe it's worth a look

https://forum.arduino.cc/t/using-multiple-spi-devices-on-arduino-mega-2560/582375/17?u=ec2021

@ec2021

Thank you for leaving an answer.
I hope today will be a good day too~ ^^

@ec2021
@anon92864395
@david_2018
@intstarep

Here's what we got from our long tests:

  1. I knew that problems would arise over time.

  2. If saving is not possible, I tried to solve it by using 'Softreset (ex. WATCH DOG)'.

  3. But something strange happened.

  • Softreset (ex. WATCH DOG) : not work (SD card)
  • Power restart: work (SD card)