Pages: [1]   Go Down
Author Topic: [SOLVED] microSD card reading problem  (Read 604 times)
0 Members and 1 Guest are viewing this topic.
Colorado
Offline Offline
Edison Member
*
Karma: 47
Posts: 1562
Reviving dead brain cells with Arduinos.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Can someone tell me why this code fails:
Code:
#include <SD.h>

Sd2Card card;
SdVolume volume;
SdFile root;
File myFile;

const int chipSelect = 10;

void setup() {
  Serial.begin(57600);
  while (!Serial) {
    ;
  }
  Serial.print("Initializing SD card ... ");
  pinMode(10, OUTPUT);

  if (!card.init(2, chipSelect)) {
    Serial.println("failed!");
    return;
  } else {
    Serial.println("done!");
  }
  
  Serial.print("\nCard 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 cookie!");
      break;
  }
  
  if (!volume.init(card)) {
    Serial.println("Can't open volume.  Is the card formatted FAT16/FAT32?");
    return;
  }

  // What's on the card
  Serial.println("\nFiles on card:");
  root.openRoot(volume);
  root.ls(LS_R | LS_DATE | LS_SIZE);
  Serial.println();
  
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failure!");
    return;
  }
  
  // Read PATTERN1.TXT file ...
  myFile = SD.open("pattern1.txt");
  if (myFile) {
    while (myFile.available()) {
      Serial.write(myFile.read());
    }
    myFile.close();
    Serial.println("\nDone!");
  } else {
    Serial.println("Can't open file!");
    return;
  }
}

void loop(void) {
}

Serial monitor output is as follows:
Code:
Initializing SD card ... done!

Card type: SD2

Files on card:
PATTERN3.TXT  2013-06-04 04:14:48 12955
PATTERN1.TXT  2013-06-04 04:13:56 18764
PATTERN2.TXT  2013-06-04 04:14:20 16586

Card failure!

Which tells me it's failing specifically at the SD.begin() portion of the code.  But why?
« Last Edit: June 05, 2013, 07:44:12 pm by KirAsh4 » Logged

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 545
Posts: 27357
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Is that fat16lib's SD library?
If not, use that.
http://code.google.com/p/fat16lib/
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Colorado
Offline Offline
Edison Member
*
Karma: 47
Posts: 1562
Reviving dead brain cells with Arduinos.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Figure it out.  The SD library forced SPI speed to SPI_HALF_SPEED which, for some reason, isn't working.  If I change it to the value '2' instead, the above sketch works fine.  From SD.cpp:
Code:
boolean SDClass::begin(uint8_t csPin) {
  /*
    Performs the initialisation required by the sdfatlib library.
    Return true if initialization succeeds, false otherwise.
   */
  return card.init(SPI_HALF_SPEED, csPin) &&
         volume.init(card) &&
         root.openRoot(volume);
}

If I change that single line to:
Code:
 return card.init(2, csPin) &&
... everything works.

So the question now is, why won't SPI_HALF_SPEED work?  Is it because of the hardware being used?  I'm passing signals through a logic level converter and then to the breakout.

And if it IS the hardware, what are my options?  A different breakout?  I don't want to have to be editing the library files every time I need to install/upgrade the Arduino IDE.  Seems stupid.
Logged

Colorado
Offline Offline
Edison Member
*
Karma: 47
Posts: 1562
Reviving dead brain cells with Arduinos.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Is that fat16lib's SD library?
If not, use that.
http://code.google.com/p/fat16lib/

No, it's the default SD library that comes with the IDE.  For some reason, the Fat16 library keeps corrupting my cards.  Same exact setup.
Logged

Colorado
Offline Offline
Edison Member
*
Karma: 47
Posts: 1562
Reviving dead brain cells with Arduinos.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Oh, and I tried using the FAT16/FAT32 library from here: http://code.google.com/p/sdfatlib/

Which seems to be the same thing you've quoted above.  When I try to run the SdInfo sketch from that library, I get this:
Code:
SdFat version: 20130629

type any character to start
cardSize failed
SD errorCode: 0X10
SD errorData: 0X1

type any character to start
Logged

0
Offline Offline
Edison Member
*
Karma: 67
Posts: 1656
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

SD.h is just a wrapper for an old version of my SdFfat library so that is what you are using in both cases.

card.init(2, csPin) runs the card at 1/4 speed.  You have an SPI problem, maybe your wiring is not clean enough to run at high speed.

Quote
SD errorCode: 0X10
SD errorData: 0X1

This is a read error for one of the SD card's info registers.  This is almost always due to problems with the SPI bus.

The standard SD.h wrapper does not allow you to set the SPI bus speed, it always runs at 1/2 speed.  New versions of SdFat allow the bus speed to be set with the second argument of sd.begin(csPin, speed).

You will be "corrupting your cards" unless you fix the SPI problem or run the SPI bus at very slow speeds.

Logged

Colorado
Offline Offline
Edison Member
*
Karma: 47
Posts: 1562
Reviving dead brain cells with Arduinos.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

card.init(2, csPin) runs the card at 1/4 speed.  You have an SPI problem, maybe your wiring is not clean enough to run at high speed.
I'm assuming it's because I'm passing the signals through a level converter to go from 5V to 3V3 and back.  I'm waiting for a different card breakout that has a hex converter on it, see if that makes any difference.
Logged

Colorado
Offline Offline
Edison Member
*
Karma: 47
Posts: 1562
Reviving dead brain cells with Arduinos.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, that was the problem.  I replaced the lvel converter for a TXB0108 (bidirectional voltage-level translator) and SdInfo now works both as SPI_HALF_SPEED as well as at SPI_FULL_SPEED.  Thanks folks!

Onward we go ...
Logged

Pages: [1]   Go Up
Jump to: