[SOLVED] microSD card reading problem

Can someone tell me why this code fails:

#include <SD.h>

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

const int chipSelect = 10;

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

  if (!card.init(2, chipSelect)) {
  } else {
  Serial.print("\nCard type: ");
  switch(card.type()) {
    case SD_CARD_TYPE_SD1:
    case SD_CARD_TYPE_SD2:
      Serial.println("Unknown cookie!");
  if (!volume.init(card)) {
    Serial.println("Can't open volume.  Is the card formatted FAT16/FAT32?");

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

void loop(void) {

Serial monitor output is as follows:

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?

Is that fat16lib's SD library?
If not, use that.

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:

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) &&

If I change that single line to:

  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.

Is that fat16lib's SD library?
If not, use that.
Google Code Archive - Long-term storage for Google Code Project Hosting.

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.

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:

SdFat version: 20130629

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

type any character to start

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.

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.

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.

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 …