Pages: [1]   Go Down
Author Topic: SD lib:SD.exists() returns TRUE if SD is removed  (Read 13165 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 10
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello, I really like the new SD library, but there is the following issue:

Code:
#include <SD.h>
File myFile;
void setup() {
  Serial.begin(9600);
  Serial.print("Initializing SD card...");
  pinMode(10, OUTPUT);
  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
}

void loop() {
  if(SD.exists("testfile.txt")) Serial.println("Fiel Exists so SD seems to be in");
  else Serial.println("Fiel does NOT exists or SD is not in socket");
  delay(1000);
}

SD.exists() does return true or false, depending if the file could be found or not. But if you pull out the SD while the loop() is running, SD.exists() still returns TRUE.

Basically I like to use SD.exists() to check if a certain file is there to detect if my SD is in the socket or not because there is no other function within the SD library.

Is there any other way to make sure the SD is in the socket?
How ever, SD.exists() should not return TRUE if the file is not there for sure smiley
Logged

0
Offline Offline
Edison Member
*
Karma: 64
Posts: 1634
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The file may be found in a cached directory block.  The only sure way to detect removal of the SD is to use the SD detect switch on the SD socket.
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 217
Posts: 13705
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
The only sure way to detect removal of the SD is to use the SD detect switch on the SD socket.

Sample code?
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

0
Offline Offline
Edison Member
*
Karma: 64
Posts: 1634
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If card detect is connected to a digital pin you enable the pull up and do a digitalRead.  You get low if the card is in the socket.

Making your app work is not so easy.  The app must know the card is going to be removed and close any files open for write.

The app then tells the user it is ok to remove the card.

If a new card is inserted, it must be initialized by calling begin().

This is no different than using removable storage with a PC or Mac.  You can't just pull a card from the socket while an app is accessing it.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 10
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for your suggestion.
But the SD socket I use does not have a Pin to detect that the card is present.
How ever, I think such a pin/switch is optional so shouldn't the Library be able to detect the availability of the SD itself?

But even if you think that it is unnecessary, how can I now detect that the card is present?
I am not familiar with SPI, but my idea would be to send a "test"-signal to the SD.  Googling for Arduino+SD+SPI+returned many results but until now I did not find a sample.
Any Ideas?

Thanks a lot in advance.
Logged

0
Offline Offline
Edison Member
*
Karma: 64
Posts: 1634
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

All sockets that I have seen have a card detect switch and write lock switch.  There are 11 pins on the socket.  nine go to the SD and the outside two on the side with narrow spacing are the switches.

There is no simple reliable SPI command to detect the SD card.

Card removal must be handled by the app as I stated above.  Card present is just digitalRead(CD_PIN) is low.  

Shields have no uniform connection to the switches so it is easier for the app to handle them since it is so simple.

Why have an extra begin() parameter for the CD_PIN, allocate RAM to remember the pin number so the library can return digitalRead(CD_PIN)?

MicroSD sockets also have a CD switch.  I have tested CD on the Gravitech and Adafruit micoSD breakouts.

I have not been able to make CD work on the new Arduino Enet shield.  CD and WP are connected to analog 0 and 1 with pullups.  My shield may be defective.
« Last Edit: January 10, 2011, 10:43:21 am by fat16lib » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 10
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the answer.
My CardSocket does not have this Card Detect because I had to make it myself using a mSD-to-SD adapter.
But I guess this is my problem, not a general one.
How ever, the original reason to post this Thread was the behavior of exists() ( and begin() in some way )

Let's assume I have a socket with the CardDetect pin, I pull the card out and insert it/another one again. I still need a way to detect if a File exists after that, and that is not possible if exists() reads the available files from a buffer.
And calling begin() again seems to fail. It returns FALSE because it thinks it is already initialized I guess (it would return TRUE if initialisation was successful). But there is no end() or something to destroy the object.
Logged

0
Offline Offline
Sr. Member
****
Karma: 0
Posts: 375
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

That's still something that is better handled by your application.  If needed you could attach an interrupt to the CD pin and handle it that way.  But as was mentioned, if the card is pulled while an action is in process you may still have problems.
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 217
Posts: 13705
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@fat16lib, thanx for explaining,
« Last Edit: January 10, 2011, 02:40:33 pm by robtillaart » Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

0
Offline Offline
Edison Member
*
Karma: 64
Posts: 1634
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You should contact the author of the SD library wrapper about SD.begin(), the lack of SD.end() and the behavior of SD.exists().

I believe the SD wrapper is a sensible way to simplify the use of SdFat.  I don't think this simplicity should be sacrificed for more features.

SD is a wrapper for my SdFat library.  If you need more features like SdVolume::cacheFlush() you can use SdFat without the wrapper.

To always flush the cache makes no sense.  the SD wrapper has already sacrificed a great deal of performance for simplicity.

See http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1293975555
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 10
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I will try to find the author. But there is no email or name written in the wrapper's files. Only the copyright points to SparkFun. Maybe I have luck on IRC.

I got a new SD socket now with the CardDetect switch/pin (finally it was in stock again). Still the wrapper is unusable if you want to remove the card from the socket because you can not de-initialize the SD object to initialize it again later.
Logged

0
Offline Offline
Newbie
*
Karma: 1
Posts: 1
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The reason you cannot call begin repeatedly is the the root file object is still open. If you add a root.close() to the begin routine in SD.cpp then you can use begin repeatedly and verify the presence of a card.

Code:
boolean SDClass::begin(uint8_t csPin) {
  /*

    Performs the initialisation required by the sdfatlib library.

    Return true if initialization succeeds, false otherwise.

   */
  if (root.isOpen()) root.close();      // allows repeated calls
  return card.init(SPI_HALF_SPEED, csPin) &&
         volume.init(card) &&
         root.openRoot(volume);
}
Logged

Pages: [1]   Go Up
Jump to: