MicroSD not able to initialize often

I have several mega's and WL5100 ethernet shields and sd cards.
but the have all the same issue.
when i upload my code the SD card isn't working any more.
when i disconnect it from my laptop and connect it again. it usualy works after sd card failed message.
but sometimes i need to power off and on several time before it start up.

if it works and i dont restart my arduino it keeps working without any problem.
but if i disconnect the power and power it on the issue is back.

any idea whats wrong

Try this. It disables the w5100 SPI while you are setting up the SD.

#include <SD.h>

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

  // disable w5100 SPI wile setting up SD
  pinMode(10,OUTPUT);
  digitalWrite(10,HIGH);

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

void loop() {
}

I think I am experiencing a similar issue using the Latest HW for Ethernet shield and Mega 2560 -

I had intermittent failures, where the SD card would init and I could list all files on the card - but not read any file contents. Sometimes a re-start could cause the card init to fail.

I think it is related (in part) to the SPI IO.

At the time, I was setting pin 10 as an output, and high.
The mistake I was making was that I thought 'SS' (pin 53), was the SD chip_select, and I was passing SS to the sd.init function.

It seemed when I did this the operation was flaky at best - though it did work in part.

Does anyone have a definitive description of what the following pins do:
Pin 4 = CS_SD ?
Pin 10 = CS_Ethernet ?
Pin 53 (SS) = Must be set as an output, and preferably pulled high ?

I plan on trying to trace the PCB scheamtics, but if anyone has that done, it would be great.

Digital pin 4 is the SD slave select.
Digital pin 10 is the w5100 slave select.
Digital pin 53 is the default slave select.

The SD.begin(4) will set the default slave select as OUTPUT and HIGH.

If you are using a Mega, you must disable the w5100 slave select before initializing the SD. If you don't, the w5100 will trash up the SPI, and chances are the setup will fail.

The SPI data lines are on the ICSP pins as well as on pins 50-52 on the Mega and pins 11-13 on the Uno. The ICSP connector is how the ethernet shield gets those SPI lines from either model, not the digital pins.

This post has code that I use to initialize both devices if I want to use them together.

Thanks SurferTim, I'll give that a shot.
Hopefully it will be the end of my reset-related woes!

tails_naf:
Hopefully it will be the end of my reset-related woes!

It was for me! I've had no problems with the reset and the SD since.

I forgot to mention that on the Uno, digital pin 10 is the default slave select as well as the w5100 slave select. Since the SD.begin(4) call sets the default slave select as OUTPUT and HIGH, the w5100 is disabled in the SD setup on the Uno. But on the Mega, this is not the case. It must be disabled by your setup code.

I see your code but is the code correct
because you mention you have to disable the W5100 chip. but you set pin 10 high before initializing the SD card.
after the initializing you set pin 10 high again.

logical i think

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

// disable w5100 SPI while setting up SD
pinMode(10,OUTPUT);
digitalWrite(10,LOW);

Serial.print("Starting SD...");
if(!SD.begin(4)) Serial.println("failed");
else Serial.println("ok");
// SD.begin() returns with its SPI disabled. Good SD library!

Serial.print("Starting w5100...");

if(!Ethernet.begin(mac)) Serial.println("failed");
else Serial.println("ok");

// Ethernet.begin() returns with the SPI enabled (bug?), so disable it. Bad Ethernet library!
digitalWrite(10,HIGH);

The Ethernet.begin() function is a bad puppy! :frowning: It returns with the w5100 SPI enabled. I think this is a bug. I did not say the functions were totally bug free. To patch the bug, you must disable it after that call.

The SD.begin(4) function returns with its SPI disabled like all SPI-based libraries should. It is a good puppy! :slight_smile:

SurferTim, thx

added the lines like example below and it works like a charm.
I had the initialisation issue almost every boot but now only one time before it continues.
after i moved it before the while it's completly gone.

pinMode(10,OUTPUT);
while (!SD.begin(chipSelect)) {
digitalWrite(10, HIGH);
Serial.println("Card failed, or not present");}

  // enable w5100 SPI
  pinMode(10,OUTPUT);
  // now enable the SD SPI at the same time
  while (!SD.begin(chipSelect)) {
  // now disable the w5100 SPI after the SD fail
  digitalWrite(10, HIGH);
  Serial.println("Card failed, or not present");}

That will cause problems. You are enabling the w5100 SPI, then calling the SD.begin() function using the SPI.

I think this is what you said worked.

  pinMode(10,OUTPUT);
  digitalWrite(10, HIGH);

  while (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
  }

This code works on an Arduino Due with an Arduino Ethernet shield and micro SD card:

byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1,9);

void setup()
{

pinMode(10, OUTPUT);
digitalWrite(10,LOW);

// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
// start the Ethernet connection and the server:

Ethernet.begin(mac, ip);
server.begin();

Serial.print("server is at ");
Serial.println(Ethernet.localIP());

if (!SD.begin(4))
Serial.println("SD initialization failed.");
}

Note the digitalWrite(10, LOW).

Note the digitalWrite(10, LOW).

Not on the ethernet shield. All other SPI slave selects must be HIGH when running another SPI device setup. You are leaving the SD slave select (digital pin 4) potentially active. With pin 4 floating, it is difficult to tell how the SD will react to the setup commands intended for the w5100.

I'm not quite sure I understand what's going on here. But with the digitalWrite LOW it works and with a digitalWrite HIGH it definitely doesn't.

Can I ask exactly how you would rewrite my setup() code above to make it rock solid? I would be extremely grateful.

Not quite answering my own question, the following:

void setup()
{

Serial.begin(9600);

pinMode(10, OUTPUT);
digitalWrite(10,LOW);

Ethernet.begin(mac, ip);
server.begin();

Serial.print("server is at ");
Serial.println(Ethernet.localIP());

digitalWrite(10,HIGH);

if (!SD.begin(4))
Serial.println("SD initialization failed.");

digitalWrite(10,LOW);

Serial.print("server is (still?) at ");
Serial.println(Ethernet.localIP());

}

Seems to work most reliably. Which is to say, set pin 10 LOW when talking to the ethernet, and HIGH when initialising the SD (it seems it can be left LOW when opening and reading SD files which in my case contain some HTML that's being served up; I haven't tried writing to the SD). Any other pattern of LOWs and HIGHs mostly stops either the SD or the ethernet or both from working, but you can sometimes leave out the digitalWrite(10,HIGH); before the SD initialisation and things will still work. Setting 10 HIGH before doing anything ethernet always stops the ethernet in its tracks.

I think I am confused (not for the first time...)

I agree with some, but not all. If you leave the SD SPI floating while starting the w5100, you will eventually have trouble. Maybe not all the time, but enough to be annoying, normally noticeable on a reboot.

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

  // disable SD SPI while starting w5100
  // or you will have trouble
  pinMode(4, OUTPUT);
  digitalWrite(4,HIGH);   

  Ethernet.begin(mac, ip);
  server.begin();
  
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
  
  // this corrects a bug in the Ethernet.begin() function
  // even tho the call to Ethernet.localIP() does the same thing
  digitalWrite(10,HIGH);
 
  if (!SD.begin(4)) 
     Serial.println("SD initialization failed.");
  // SD.begin() returns with the SPI disabled, so you need not disable it here
    
  Serial.print("server is (still?) at ");
  Serial.println(Ethernet.localIP());    
     
}

Cool! That works, and is so simple even I can understand it.

Thanks SurferTim. :slight_smile:

Hello, this is my first post. I registered to thank you and to tell you that I fixed my issue.

I had troubles with default "CardInfo" sketch with Arduino Leonardo and Ethernet Shield R3. It was not working out of the box, telling me SD card was not formatted or that it couldn't be initialized at all. I fixed with the line:
digitalWrite(10,HIGH);

Here it is my fixed sketch:

/*
  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 <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
const int chipSelect = 4;    

void setup()
{
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  Serial.print("\nInitializing SD card...");
  // On the Ethernet Shield, CS is pin 4. It's set as an output by default.
  // Note that even if it's not used as the CS pin, the hardware SS pin 
  // (10 on most Arduino boards, 53 on the Mega) must be left as an output 
  // or the SD library functions will not work. 
  pinMode(10, OUTPUT);     // change this to 53 on a mega
  digitalWrite(10,HIGH);   // >>>>>>> Added this here to fix on Arduino Leonardo

  // 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 is inserted?");
    Serial.println("* Is your wiring correct?");
    Serial.println("* did you change the chipSelect pin to match your shield or module?");
    return;
  } else {
   Serial.println("Wiring is correct and a card is present."); 
  }

  // print the type of card
  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");
  }

  // 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");
    return;
  }


  // print the type and size of the first FAT-type volume
  uint32_t volumesize;
  Serial.print("\nVolume type is FAT");
  Serial.println(volume.fatType(), DEC);
  Serial.println();
  
  volumesize = volume.blocksPerCluster();    // clusters are collections of blocks
  volumesize *= volume.clusterCount();       // we'll have a lot of clusters
  volumesize *= 512;                            // SD card blocks are always 512 bytes
  Serial.print("Volume size (bytes): ");
  Serial.println(volumesize);
  Serial.print("Volume size (Kbytes): ");
  volumesize /= 1024;
  Serial.println(volumesize);
  Serial.print("Volume size (Mbytes): ");
  volumesize /= 1024;
  Serial.println(volumesize);

  
  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);
}


void loop(void) {
  
}