SD Card Initialization Help

Did you reformat the card? I use a SanDisk 2GB card, and it needed nothing. I just stuck it in, and it worked.

Have you tried the standard SD library as a test?

#include <SD.h>

void setup() {
  Serial.begin(9600);

  Serial.print("Starting SD...");
  if(!SD.begin(12)) Serial.println("failed");
  else Serial.println("ok");
}

void loop() {
}

If you have any other devices connected to the Mega, disconnect them for this test. Insure the SD card slave select is connected to D12.

edit: How are you powering that SD module? If you are using the 3.3v bus on the Arduino, there is not enough power available on that bus to power a SD card. That bus is limited to about 50ma, and the newer SD cards require about 100ma to read/write.

I reformated the scard by computer.Fat32.
I used a SanDisk 2GB card.
and use the standard SD library

// Quick hardware test
#include <SdFat.h>
// Test with reduced SPI speed for breadboards.
// Change spiSpeed to SPI_FULL_SPEED for better performance
// Use SPI_QUARTER_SPEED for even slower SPI bus speed
const uint8_t spiSpeed = SPI_HALF_SPEED;
//------------------------------------------------------------------------------
// Normally SdFat is used in applications in place
// of Sd2Card, SdVolume, and SdFile for root.
Sd2Card card;
SdVolume volume;
SdFile root;

// Serial streams
ArduinoOutStream cout(Serial);

// input buffer for line
char cinBuf[40];
ArduinoInStream cin(Serial, cinBuf, sizeof(cinBuf));

// SD card chip select
int chipSelect;

void cardOrSpeed() {
  cout << pstr(
    "Try another SD card or reduce the SPI bus speed.\n"
    "The current SPI speed is: ");
  uint8_t divisor = 1;
  for (uint8_t i = 0; i < spiSpeed; i++) divisor *= 2;
  cout << F_CPU * 0.5e-6 / divisor << pstr(" MHz\n");
  cout << pstr("Edit spiSpeed in this sketch to change it.\n");
}

void reformatMsg() {
  cout << pstr("Try reformatting the card.  For best results use\n");
  cout << pstr("the SdFormatter sketch in SdFat/examples or download\n");
  cout << pstr("and use SDFormatter from www.sdcard.org/consumer.\n");
}

void setup() {
  Serial.begin(9600);
  while (!Serial) {}  // wait for Leonardo
  
  cout << pstr(
    "\nSD chip select is the key hardware option.\n"
    "Common values are:\n"
    "Arduino Ethernet shield, pin 4\n"
    "Sparkfun SD shield, pin 8\n"
    "Adafruit SD shields and modules, pin 10\n");
}

bool firstTry = true;
void loop() {
  // read any existing Serial data
  while (Serial.read() >= 0) {}

  if (!firstTry) cout << pstr("\nRestarting\n");
  firstTry = false;

  cout << pstr("\nEnter the chip select pin number: ");
  cin.readline();
  if (cin >> chipSelect) {
    cout << chipSelect << endl;
  } else {
    cout << pstr("\nInvalid pin number\n");
    return;
  }
  if (!card.init(spiSpeed, chipSelect)) {
    cout << pstr(
      "\nSD initialization failed.\n"
      "Do not reformat the card!\n"
      "Is the card correctly inserted?\n"
      "Is chipSelect set to the correct value?\n"
      "Is there a wiring/soldering problem?\n");
    cout << pstr("errorCode: ") << hex << showbase << int(card.errorCode());
    cout << pstr(", errorData: ") << int(card.errorData());
    cout << dec << noshowbase << endl;
    return;
  }
  cout << pstr("\nCard successfully initialized.\n");
  cout << endl;

  uint32_t size = card.cardSize();
  if (size == 0) {
    cout << pstr("Can't determine the card size.\n");
    cardOrSpeed();
    return;
  }
  uint32_t sizeMB = 0.000512 * size + 0.5;
  cout << pstr("Card size: ") << sizeMB;
  cout << pstr(" MB (MB = 1,000,000 bytes)\n");
  cout << endl;

  if (!volume.init(&card)) {
    if (card.errorCode()) {
      cout << pstr("Can't read the card.\n");
      cardOrSpeed();
    } else {
      cout << pstr("Can't find a valid FAT16/FAT32 partition.\n");
      reformatMsg();
    }
    return;
  }
  cout << pstr("Volume is FAT") << int(volume.fatType());
  cout << pstr(", Cluster size (bytes): ") << 512L * volume.blocksPerCluster();
  cout << endl << endl;

  root.close();
  if (!root.openRoot(&volume)) {
    cout << pstr("Can't open root directory.\n");
    reformatMsg();
    return;
  }
  cout << pstr("Files found (name date time size):\n");
  root.ls(LS_R | LS_DATE | LS_SIZE);

  if ((sizeMB > 1100 && volume.blocksPerCluster() < 64)
    || (sizeMB < 2200 && volume.fatType() == 32)) {
    cout << pstr("\nThis card should be reformatted for best performance.\n");
    cout << pstr("Use a cluster size of 32 KB for cards larger than 1 GB.\n");
    cout << pstr("Only cards larger than 2 GB should be formatted FAT32.\n");
    reformatMsg();
    return;
  }
  // read any existing Serial data
  while (Serial.read() >= 0) {}
  cout << pstr("\nSuccess!  Type any character to restart.\n");
  while (Serial.read() < 0) {}
}

It doesn't work.
And I used your code.

#include <SD.h>

void setup() {
  Serial.begin(9600);

  Serial.print("Starting SD...");
  if(!SD.begin(12)) Serial.println("failed");
  else Serial.println("ok");
}

void loop() {
}

But it doesn't work, too.

There is not other devices connected to the Mega, only SD card.The SDcard CS is connected to PIN 12(OUT 1).
And I used the 5V to power the SDcard.

Can you post a link to that SD card?

SurferTim:
Can you post a link to that SD card?

What do you mean? I connect the SDcard CS to PIN 12,which is Mega2560 OUT1.

It is the APM2.5 Mega2560 SCH.

APM_v2.5???.pdf (59.7 KB)

I have heard on this forum that some of the SD card modules with the voltage divider circuit rather than a true logic level converter can cause problems. As I recall, it is a signal rise and fall time challenge with the larger, newer uSD cards due to the rc component of the circuit. Maybe fat16lib or someone else can add more to that.

Mine has a logic level converter.



Yes, those resistors (R1-R4) in the bottom picture. Unless my eyes are failing (that is possible..I'm old!), those particular resistors are 10Kohm. That will add a considerable rise and fall time delay.

SurferTim:
Yes, those resistors (R1-R4) in the bottom picture. Unless my eyes are failing (that is possible..I'm old!), those particular resistors are 10Kohm. That will add a considerable rise and fall time delay.

So....How to solve it? Must I change the SD module or...?

I would see if fat16lib or someone else has more to add to this thread. It may or may not be that problem. It might help other users if you posted the make, model, and size of the SD card you have in the module, and anything you have done to it, like reformatting. Most of that can be corrected.

If it is the new rc component of that circuit, you will probably need to get another type of SD module. To insure the best performance, get one with a logic level converter, not the voltage divider.

reformatting:
Put the SD card to computer,open My Computer on the desktop,see the SDcard, right click it.Select the formatting.

This looks like an SD socket that is in many ebay ads.

This card has 10k resistors connected between 3.3V and CS, SCK, MISO, and MOSI. This may not work with many SD cards when the SPI is driven by 5V signals.

Here is an example add with circuit diagram http://www.ebay.com/itm/SD-Card-Reader-Module-for-Arduino-ARM-Read-and-Write-/200659790559?pt=LH_DefaultDomain_0&hash=item2eb8416adf.

fat16lib:
This looks like an SD socket that is in many ebay ads.

This card has 10k resistors connected between 3.3V and CS, SCK, MISO, and MOSI. This may not work with many SD cards when the SPI is driven by 5V signals.

Here is an example add with circuit diagram http://www.ebay.com/itm/SD-Card-Reader-Module-for-Arduino-ARM-Read-and-Write-/200659790559?pt=LH_DefaultDomain_0&hash=item2eb8416adf.

My SD card is driven by 5V power.It is connected with 5V,not 3.3V.But it is still not work.

They are trying to tell you that the resistors are in series with the signals MOSI, SCK, and CS. This is because the arduino signals are 5V and the SD card is 3.3v. Yes, you are powering it with 5V, but there is a regulator on your module that brings it to 3.3V. That does not change the signals, though. So some cheaper modules use resistors in series to do the level translation between the 5V and 3.3v.

They are pointing out that this may cause problems. A more correct way to do it is to use a level translator IC like a CD4050 or 74HC244.

But... on your Arduino board, I see a jumper for selecting between 3.3v and 5V MISO levels. Perhaps you need to jumper that.

Actually, Retroplayer, I thought that too, but it is worse than that. The schematic fat16lib posted a link to above shows those 10K resistors are pullup resistors, not in series with the inputs. The 5v outputs of the Arduino are connected directly to the 3.3v inputs of the SD card.

Ahh... well, I looked at the schematic for the arduino board the OP is using and it appears that it has a level translator built in so the signals should be 3.3V. A pretty nice (but expensive board) actually.

I see. If the digital pins on that Mega board are 3.3v, then he is one of the lucky ones. But looking at that board, I'm not sure if it is even wired correctly for the code I would suggest.

Sorry, my english is poor.....So..
I understand you now.
But what is OP?

I looked at the schematic for the arduino board the OP is using and it appears that it has a level translator built in so the signals should be 3.3V.


Now I have two solutions if I didn't understand wrong.

  1. Select 3.3v MISO levels for the board if possible. Thus,I can get the CS,SCK,MISO,MOSI signals with 3.3V from the board.
  2. Change the SD card with a level translator IC.Thus, I can convert the CS,SCK,MISO,MOSI signals from the board to 3.3V.

Am I right?Thanks a lot!

That is correct.

OP means Original Poster = you.