SdFat Read Error Troubleshooting

Hiy'all,

Using the SdFat library to read some files. Everything works fine, except some files won't read at all (trigger the "failed" error) and there are just seemingly random failures here and there. Is there some way I can make this more robust? It's just .read() and .seekSet() which I try to skip if they aren't successful so I'm not sure why it would fail. I tried putting in some delay between .read() but it didn't help. It's for an LED table top, I'm reading some animations off the SD card, I'll post a project page when it's done.

void setup() {
  Serial.begin(9600);
  randomSeed(analogRead(0));
  delay(400);  // catch Due reset problem
  if (!sd.begin(chipSelect, SPI_FULL_SPEED)) 
    sd.initErrorHalt();

  file = files[random(fileCount)];
  
  strip.begin();
  strip.setPixelColor(0, 0, 0, 0);
  strip.show();  
}

void loop() {

  rep = rep + 1;
  if(rep > reps)
  {  
    rep = 0;
    file = files[random(fileCount)];
    Serial.println(file);
  }
    
  if (!myFile.open(file, O_READ)) {
    // error
    sd.errorHalt("failed");
    // sd.begin(chipSelect, SPI_HALF_SPEED);
    rep = 100;
    return;
  }

  int data;
  
  int column = 0;
  int row = 0;
  int frame = 0;
  
  while ((data = myFile.read()) >= 0)
  {
    // read red
    int r = data;
    delay(.5);
    // read green
    if((data = myFile.read()) < 0)
      break;
    int g = data;
    delay(.5);
    // read blue
    if((data = myFile.read()) < 0)
      break;
    int b = data;
    
    // set pixel address
    byte address = addressMatrix[row][column];
    // set pixel color
    strip.setPixelColor(address, r, g, b);
    
    // next column
    column = column + 1;
    
    // all the columns we need for this matrix
    if(column > ledcols)
    {       
      // reset column count
      column = 0;
      // increment row
      row = row + 1;
      
      // seek to row (skip extra pixels)
      if(myFile.seekSet((frame*framesize)+(row*rowsize)) == 0)
        break;
      
      // all the rows we need for this matrix
      if(row > ledrows)
      {  
        // turn off first pixel (7x7 matrix, 1 unused pixel)
        strip.setPixelColor(0, 0, 0, 0);
        // send current frame to strip
        strip.show();
        
        // reset row count
        row = 0;
        // increment frame
        frame = frame + 1;
        
        // pause for animation speed
        delay(delaytime);
        
        // seek to next frame
        if(myFile.seekSet(frame*framesize) == 0)
          break;
      }
    }
  }
  
  // close the file
  myFile.close();
}

You haven't posted enough code to find any program problems.

Here are several suggestions for finding the problem.

First rule out an SD low level I/O error by adding this print statement after the error is detected.

  Serial.println(sd.card()->errorCode(), HEX);

If it prints a nonzero value, a low level SD I/O error occurred and the error code is defined in Sd2Card.h

The most common reason for seekSet() to fail is an attempt to seek beyond end-of-file. Check that the seek position is less that the file size.

  uint32_t pos = (frame*framesize)+(row*rowsize);
  if (!myFile.seekSet(pos)) {
    if (pos >= myFile.fileSize()) Serial.println("bad seek position");
  }

If read() fails, check for end-of-file.

  if((data = myFile.read()) < 0) {
    if (myFile.available() == 0) Serial.println("read at EOF");
  }