Go Down

Topic: SD Reset / Switch Cards (Read 6828 times) previous topic - next topic

zappzapp

Jul 13, 2011, 02:42 pm Last Edit: Jul 13, 2011, 02:44 pm by zappzapp Reason: 1
I am using an SD card, to provide my application with a configuration file.
If the user wants to change the system configuration, he would remove the SD card, edit the configuration files and put it back in (or just replace it with a different card containing a prepared configuration).
I can detect card insertion with an interrupt generated by my card holder. At the moment I am not writing to the card, only reading from it, so possible data loss should not be a problem when switching cards. The interrupt gives me a warning about 100ms ahead of losing access to the card though so I should be able to close all files.

To access the card, I use the sd lib as shown in the SD/DumpFile example.
This is the example code (just a copy paste):
Code: [Select]
/*
  SD card file dump

This example shows how to read a file from the SD card using the
SD library and send it over the serial port.

The circuit:
* SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4

created  22 December 2010

This example code is in the public domain.

*/

#include <SD.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()
{
  Serial.begin(9600);
  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(10, 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.");
 
  // 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");

  // if the file is available, write to it:
  if (dataFile) {
    while (dataFile.available()) {
      Serial.write(dataFile.read());
    }
    dataFile.close();
  } 
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
  }
}

void loop()
{
}

The problem is, that SD.begin() works exactly one time. The first time I call it while there is a card present, it returns TRUE, I can read the card, all is fine.
But any subsequent calls of SD.begin() will return FALSE. It does not matter if there is a card present, or not.
When the new card gets inserted, I want to initialize it again. But I can't use SD.begin() anymore, it will just default to FALSE now.

SD.begin() code is:
Code: [Select]
  return card.init(SPI_HALF_SPEED, csPin) &&
         volume.init(card) &&
         root.openRoot(volume);

So I tried calling these 3 parts one by one in this order, to see where the FALSE originates from. Oddly enough, every single on of them returns TRUE, but begin() still returns FALSE.
Anyway still I can not open any files on the newly inserted card after doing this. There must be something in the SD class, that gets set the first time you call begin and then obstructs further initializations, but I can't figure out what it is.

Any idea, how I can get the global SD object back to square one, so I can use begin() again?
Or maybe steps to initialize another card.
Whichever requires less hacking the lib files.

Thanks

fat16lib

Add a root.close() call to the begin() function like this:
Code: [Select]
  root.close();
  return card.init(SPI_HALF_SPEED, csPin) &&
         volume.init(card) &&
         root.openRoot(volume);


SD.h is a wrapper for an old version of SdFat so you might want to consider using the new version of SdFat:

http://code.google.com/p/sdfatlib/downloads/list

The new SdFat is as easy to use as SD.h and has many new features and improvements.

zappzapp

Thank you for the quick reply.
This fixed the problem.

I got the new lib now, but this project is almost finished, so I'll use it in my next one.

Go Up