[SOLVED] SD Card openNextFile() Issue, Arduino Mega 2560 + Ethernet Shield

I am trying to use the Arduino Mega 2560 as a web server and data logger. I would like to be able to look at the files stored on the SD card, but I began having problems with openNextFile() (it wouldn’t). It appears that all files before anything that has been opened seem to be permanently removed from the list (though it is still possible to access the files by simply using .open()).

I then decided to test this theory with the example listfiles (to ensure that my rather large code wasn’t generating any memory issues) and encountered the same problem.

With the typical listfiles code, I receive this correct output:

Initializing SD card...initialization done.
SLIVE.HTM 8634
CLIVE.HTM 8761
ELIVE.HTM 10238
EP_STYLE.CSS 2190
GENSETUP.HTM 7982
INDEX.HTM 1303
MTRSETUP.HTM 12904
MTRSETUP.XML 446
NOPAGE.HTM 1252
RESET.HTM 1233
SETUP.XML 215
GENSETUP.XML 253
PASTDOWN.HTM 1288
PASTVIEW.HTM 1228
TEST.TXT 27
PSTDOWN2.HTM 207
PSTDOWN1.HTM 1043
done!

With the new code, I added another File variable, and open and close “index.htm” before opening root. Adjusted code here:

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

File root;
File dummy;  //  I added this ------------------------------------------------------------------------- 

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial.print("Initializing SD card...");

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

  dummy = SD.open("index.htm");  // I added this --------------------------------------------------------
  dummy.close();                 // I added this --------------------------------------------------------
  
  root = SD.open("/");

  printDirectory(root, 0);

  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
      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);
    }
    entry.close();
  }
}

Now the output is this:

Initializing SD card...initialization done.
MTRSETUP.HTM 12904
MTRSETUP.XML 446
NOPAGE.HTM 1252
RESET.HTM 1233
SETUP.XML 215
GENSETUP.XML 253
PASTDOWN.HTM 1288
PASTVIEW.HTM 1228
TEST.TXT 27
PSTDOWN2.HTM 207
PSTDOWN1.HTM 1043
done!

If I change “index.htm” to “test.txt”, the result is:

Initializing SD card...initialization done.
PSTDOWN2.HTM 207
PSTDOWN1.HTM 1043
done!

It seems like openNextFile() increments based on other variables that are no longer in use. It reads most of the files if you open and close “slive.htm” after any other files are opened and closed. This is a really sloppy way to get around it though, because I am giving up one file and there is no guarantee which file is at the top, since it does not seem to be listed in any particular way.

Is there any way to work around this? Some sort of reset for the SD library?

openNextFile opens the next file in a directory. Your problem is that SD.h has an internal version of root and you get a copy when you open root. This copy may not be positioned at the beginning of the directory.

Call root.rewindDirectory() to set the position to the beginning.

Thanks! I see my problem was not reading all of the library's documentation. :-[