Skip to content

SD.exists() has weird side-effects, breaks subsequent SD calls #11

Open
@agdl

Description

@agdl

From @blowback on January 17, 2013 13:20

If I take the listfiles.ino example and change the chip select to 4, I can get a directory listing of the contents of my SD card, as expected.

If I modify the code by adding SD.exists("foo);' immediately before the 'root = SD.open("/");' then printDirectory() no longer works - specifically, the first call to dir.openNextFile() fails.

If I move the SD.exists() line to after the SD.open("/") line, then it works again.

I tried wrapping the SD.exists() with its own SD.open().....root.close(), but that caused the directory listing to fail again.

It doesn't matter if the file tested for actually exists or not, the behaviour is the same in both cases (and SD.exists() returns the right result).

Here's the code:

/*
  SD card basic file example

 This example shows how to create and destroy an SD card file   
 The circuit:
 * SD card attached to SPI bus as follows:
 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK - pin 13
 ** CS - pin 4

 created   Nov 2010
 by David A. Mellis
 modified 9 Apr 2012
 by Tom Igoe

 This example code is in the public domain.

 */
#include <SD.h>

void printDirectory(File dir, int numTabs);


File root;

void setup()
{
   delay(5000);
  // Open serial communications and wait for port to open:
  Serial.begin(57600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  Serial.print("Initializing SD card...");
  // On the Ethernet Shield, CS is pin 4. It's set as an output by default.
  // Note that even if it's not used as the CS pin, the hardware SS pin 
  // (10 on most Arduino boards, 53 on the Mega) must be left as an output 
  // or the SD library functions will not work. 
  pinMode(10, OUTPUT);

  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

  /* ADDED CODE: this SD.exists() call will cause the dir.openNextFile()
   * call in printDirectory() to fail, regardless of whether the file
   * actually exists or not.
   */
  if(SD.exists("META.DAT"))
  {
      Serial.println("EXISTS");
  }
  else
  {
      Serial.println("DOESN'T EXIST");
  }
  /* END ADDED CODE
   */

  root = SD.open("/");

  /* ADDITIONAL: if we do our SD.exists() check here, after the SD.open("/"),
   * then it all works again.
   * HOWEVER id we wrap our SD.exists() with its own SD.open() and root.close(),
   * it goes back to being broken!
   */

  if(root)
  {
      Serial.println("root opened");
      printDirectory(root, 0);
  }
  else
  {
      Serial.println("failed to open root");
  }

  Serial.println("done!");
}

void loop()
{
  // nothing happens after setup finishes.
}

void printDirectory(File dir, int numTabs) {
   while(true) {

     File entry =  dir.openNextFile();
     if (! entry) {
       // no more files
       Serial.println("openNextFile failed");
       break;
     }
     for (uint8_t i=0; i<numTabs; i++) {
       Serial.print('\t');
     }
     Serial.print(entry.name());
     if (entry.isDirectory()) {
       Serial.println("/");
       printDirectory(entry, numTabs+1);
     } else {
       // files have sizes, directories do not
       Serial.print("\t\t");
       Serial.println(entry.size(), DEC);
     }
   }
}

Copied from original issue: arduino/Arduino#1232

Metadata

Metadata

Assignees

Labels

topic: codeRelated to content of the project itselftype: imperfectionPerceived defect in any part of project

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions