Root.ls works for me but SD.exists doesn't

Hi All,

I have an OLED screen with a micro SD card slot

and I want to read images from the card and display them on the screen.

I can’t seem to get the Arduino to read the card.

Sort of.

I have tried FAT-16 and FAT-32 cards.

I have tried Micro 32GB cards and full size, old school 32Mb cards.

I have tried using the card onboard the OLED screen. I have tried using a separate SD card shield.

I have tried two different Arduinos (Elegoo & Hero)

Same result with all of them. I can get the directory with root.ls but I cannot open any files with SD.open or SD.exists

My test code:

/*
  SD card test

  This example shows how use the utility libraries on which the'
  SD library is based in order to get info about your SD card.
  Very useful for testing a card when you're not sure whether its working or not.

  The circuit:
    SD card attached to SPI bus as follows:
 ** MOSI - pin 11 on Arduino Uno/Duemilanove/Diecimila
 ** MISO - pin 12 on Arduino Uno/Duemilanove/Diecimila
 ** CLK - pin 13 on Arduino Uno/Duemilanove/Diecimila
 ** CS - depends on your SD card shield or module.
     Pin 4 used here for consistency with other Arduino examples


  created  28 Mar 2011
  by Limor Fried
  modified 9 Apr 2012
  by Tom Igoe
*/
// include the SD library:
#include <SPI.h>
#include <SD.h>

// set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
SdFile root;

// change this to match your SD shield or module;
// Arduino Ethernet shield: pin 4
// Adafruit SD shields and modules: pin 10
// Sparkfun SD shield: pin 8
// MKRZero SD: SDCARD_SS_PIN
int chipSelect = 10;

File myFile;

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
  }


  // we'll use the initialization code from the utility libraries
  // since we're just testing if the card is working!
  if (!card.init(SPI_HALF_SPEED, chipSelect)) {
    Serial.println("initialization failed. Things to check:");
    Serial.println("* is a card inserted?");
    Serial.println("* is your wiring correct?");
    Serial.println("* did you change the chipSelect pin to match your shield or module?");
      Serial.println(chipSelect);
    Serial.println("");
  } else {
    Serial.println("Wiring is correct and a card is present.");
  }



  // print the type of card
  Serial.println();
  Serial.print("Card type:         ");
  switch (card.type()) {
    case SD_CARD_TYPE_SD1:
      Serial.println("SD1");
      break;
    case SD_CARD_TYPE_SD2:
      Serial.println("SD2");
      break;
    case SD_CARD_TYPE_SDHC:
      Serial.println("SDHC");
      break;
    default:
      Serial.println("Unknown");
  }

  // Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
  if (!volume.init(card)) {
    Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
    while (1);
  }

  Serial.print("Clusters:          ");
  Serial.println(volume.clusterCount());
  Serial.print("Blocks x Cluster:  ");
  Serial.println(volume.blocksPerCluster());

  Serial.print("Total Blocks:      ");
  Serial.println(volume.blocksPerCluster() * volume.clusterCount());
  Serial.println();

  // print the type and size of the first FAT-type volume
  uint32_t volumesize;
  Serial.print("Volume type is:    FAT");
  Serial.println(volume.fatType(), DEC);

  volumesize = volume.blocksPerCluster();    // clusters are collections of blocks
  volumesize *= volume.clusterCount();       // we'll have a lot of clusters
  volumesize /= 2;                           // SD card blocks are always 512 bytes (2 blocks are 1KB)
  Serial.print("Volume size (Kb):  ");
  Serial.println(volumesize);
  Serial.print("Volume size (Mb):  ");
  volumesize /= 1024;
  Serial.println(volumesize);
  Serial.print("Volume size (Gb):  ");
  Serial.println((float)volumesize / 1024.0);

  Serial.println("\nFiles found on the card (name, date and size in bytes): ");
  root.openRoot(volume);

  // list all files in the card with date and size
  root.ls(LS_R | LS_DATE | LS_SIZE);

  if (SD.exists("TEST.TXT")){
     Serial.println("SD.exists found TEST.TXT");}

  else {Serial.println("SD.exists failed to find TEST.TXT");}
     
  
  // re-open the file for reading:
  myFile = SD.open("TEST.TXT");
  if (myFile) {
    Serial.println("SD.open failed to create TEST.TXT");

    // read from the file until there's nothing else in it:
    while (myFile.available()) {
      Serial.write(myFile.read());
    }
    // close the file:
    myFile.close();
  } else {
    // if the file didn't open, print an error:
    Serial.println("SD.open failed to create TEST.TXT");
  }
}

void loop(void) {
}

This is the output I get:

10:38:08.197 -> Wiring is correct and a card is present.
10:38:08.244 ->
10:38:08.244 -> Card type: SD1
10:38:08.292 -> Clusters: 60237
10:38:08.292 -> Blocks x Cluster: 1
10:38:08.292 -> Total Blocks: 60237
10:38:08.338 ->
10:38:08.338 -> Volume type is: FAT16
10:38:08.384 -> Volume size (Kb): 30118
10:38:08.384 -> Volume size (Mb): 29
10:38:08.384 -> Volume size (Gb): 0.03
10:38:08.431 ->
10:38:08.431 -> Files found on the card (name, date and size in bytes):
10:38:08.524 -> SYSTEM~1/ 2023-06-30 16:43:04
10:38:08.524 -> WPSETT~1.DAT 2023-06-30 16:43:04 12
10:38:08.571 -> INDEXE~1 2023-06-30 16:43:06 76
10:38:08.616 -> TEST.TXT 2023-06-30 16:54:36 584
10:38:08.663 -> SD.exists failed to find TEST.TXT
10:38:08.710 -> SD.open failed to create TEST.TXT

Any thoughts?

Cheers,

Wilson.

Instead of using SD.open("TEST.TXT"), try using SD.open("/TEST.TXT")

Thanks for the suggestion!

I was hoping it would be something stupid (and it probably actually is) but sadly, adding ‘/’ did not change anything.

I see...

  1. verify the File Path: make sure that the file "TEST.TXT" is located in the root directory of the SD card.
  2. check the filename sensitivity: try : test.txt

Well… this is interesting… although root.ls identifies the file as” TEXT.TXT” it is in fact “test.txt”

However, changing the file name to “test.txt” seems to have had no effect.

Is this possibly a permissions thing?

I have permissions to list the root directory but NOT permissions to use SD ?

Are permissions even a thing on Arduinos?

Try this:

 if (SD.chmod("test.txt", FILE_WRITE)) {
      Serial.println("Changed file permissions successfully.");
    } else {
      Serial.println("Failed to change file permissions.");
    }

OK, either chmod isn’t a thing on Arduinos or my version of the SD lib does not have it.

OK, I purchased a MKR ZERO with onboard SD card.

I used the same micro SD card from previous experiments (32GB Fat-32) and... it works.

Using the same code but compiled for SAMD.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.