Go Down

Topic: SD Card wont initialize - SainSmart Arduino uno and ethernet shield  (Read 7073 times) previous topic - next topic

djx18

I have read many forum posts and have tried a lot of different configuration changes with CS Pin and the digitalWrite(10...) . But I still cant get my SD card initialized. I have tried two separate SD cards and have formatted them with FAT32 using https://www.sdcard.org/downloads/formatter_4/ utility.

This the Uno and Ethernet shield that I have. SainSmart uno and ethernet shield http://www.sainsmart.com/sainsmart-uno-r3-improved-version-ethernet-shield-w5100-for-arduino.html

I have been trying to use the sample SD card program which I have pasted below:

Has any one used the sainsmart ethernet shield and uno? Did they get the SD card working?

I keep getting the following error:

Initializing SD card...initialization failed. Things to check:
* is a card is inserted?
* Is your wiring correct?
* did you change the chipSelect pin to match your shield or module?

Any help is much appreciated!!!

Code: [Select]

/*
  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


  // 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) {
 
}

Peter_n

Is there a way to test them apart from each other ?
Do you have another Arduino Uno or another Ethernet shield ?

The SD card and the Etherenet chip use both the SPI bus. One of them is selected with a chip select.
In your code you set pin 10 as output, but that sets it also low. Low means active, so the Ethernet chip is active.
That is why your SD bus is not working.

Could you replace the pinMode ( 10 , OUTPUT ) ;
with the code here : http://forum.arduino.cc/index.php?topic=281741.msg1980190#msg1980190
That sets every chip select as output and as high.
After the delay of 1ms the SPI bus is ready to be used.

djx18

I dont have another arduino or ethernet shield at the moment. I had bought an Arduino mega and ethernet shield from Amazon (sainsmart brand) and I had the same issue with the mega as well. I returned both and ordered the arduino uno and ethernet shield from sainsmart's website. I had tried pin 53 with the mega but after 2 days of tinkering I gave up and returned the mega/ethernet shield and bought this uno kit instead.  

Thanks for the forum post. I tried your recommendation but its still not working (see code below). Considering that I couldn't get the Mega working either, I definitely think I am doing something wrong with the code or just missing some basics...

Any other suggestions are really appreciated.

Code: [Select]

/*
  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 <SPI.h>
#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 ( SS, OUTPUT);    // pin 10 on Uno, pin 53 on Mega
  digitalWrite( SS, HIGH);

  pinMode( 4, OUTPUT);       // SD chip select at pin 4
  digitalWrite( 4, HIGH);

  pinMode( 10, OUTPUT);     // W5100 chip select at pin 10
  digitalWrite( 10, HIGH);

  // SPI bus is now idle and ready to be used.
  delay(1);

  // we'll use the initialization code from the utility libraries
  // since we're just testing if the card is working!
   if (!SD.begin(4)) Serial.println("failed");
  else Serial.println("OK");

  // 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) {
  
}


Peter_n

What is "still not working" ?

This is my output with Uno + Ethernet Shield in Arduino 1.5.8 :
Code: [Select]

Initializing SD card...OK

Card type: Unknown
Could not find FAT16/FAT32 partition.
Make sure you've formatted the card

I call that : "It is working". Perhaps the sketch is wrong, but it is working.
Where is your card.init ?

I think you are trying to run the CardInfo sketch.
http://arduino.cc/en/Tutorial/CardInfo
That sketch needed an extra #include <SPI.h> and I have added the code to make the SPI bus idle.
After that it runs flawless.
Code: [Select]

/*
  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

 2015: included SPI.h and made SPI bus idle.
 */

#include <SPI.h>

// 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);
  Serial.println("\nCardInfo sketch");
 
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
 
  // Disable all slave selects on the SPI bus, and set 'SS' to output.
  // The Ethernet Shield uses pin 4 and 10.
  // The 'SS' is pin 10 for Uno and pin 53 for Mega.
  // But disable them all, even if SS is also pin 10.
  // The 'SS' needs to be output, for the internal SPI hardware to work properly.
  // Disable a SPI device means setting the chip select high.
  pinMode ( SS, OUTPUT);    // pin 10 on Uno, pin 53 on Mega
  digitalWrite( SS, HIGH);

  pinMode( 4, OUTPUT);       // SD chip select at pin 4
  digitalWrite( 4, HIGH);

  pinMode( 10, OUTPUT);     // W5100 chip select at pin 10
  digitalWrite( 10, HIGH);

  // SPI bus is now idle and ready to be used.
  delay(1);   


  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


  // 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) {
}


Could you try that sketch, set the serial monitor baudrate to 9600 and it should run.

djx18

@Peter_n

I just downloaded Arduino 1.5.8 and tried your code. I still got the same error in the serial monitor as before. The SD Card wont initialize. See error below:
Are there any other utilities or error codes I can extract from the SD library to better understand what the problem is?


Error:

CardInfo sketch

Initializing SD card...initialization failed. Things to check:
* is a card is inserted?
* Is your wiring correct?
* did you change the chipSelect pin to match your shield or module?

Peter_n

That sketch is to check just that.
Perhaps your hardware or the card is wrong or simply not compatible.
Did you try another card ?

djx18

That sketch is to check just that.
Perhaps your hardware or the card is wrong or simply not compatible.
Did you try another card ?
Petern_n - I have tried two separate SD cards 32GB and 64GB. I formatted them with SDCard.org formatter. At this point I need to try to get another SD Card..

Are there any error codes I can make the SD utility log so I better understand the error? Any hex codes or anything?

Has Anyone used the sainsmart uno and ethernet shield and got this working properly?

Peter_n

Don't try 32GB or 64GB, perhaps the limit is 16GB.
I use a micro SD cards of 1GB to 8GB.

The SaintSmart could be not fully compatible. I have not looked into that yet.

fat16lib

Quote
Don't try 32GB or 64GB, perhaps the limit is 16GB.
A 64 GB SDXC card will be formatted exFAT, not FAT32 so it should initialize but you will get this message with CardInfo:
Quote
Could not find FAT16/FAT32 partition.
You can use the SdFat SdFormatter example to format SDXC cards as FAT32.

The 32 GB card should work.

Quote
Are there any error codes I can make the SD utility log so I better understand the error? Any hex codes or anything?
The SdFat SdInfo example will print hex error codes.

Most likely you will get something like this:
Quote
cardBegin failed
SD errorCode: 0X1
SD errorData: 0XFF
errorCode 0X1 means the SD card is not seen and most likely the card is not the problem since you tried two cards.

This error is caused by an SPI problem such as the wrong chip select for the SD card, not disabling the Ethernet controller, or other wiring/hardware fault. 

djx18

A 64 GB SDXC card will be formatted exFAT, not FAT32 so it should initialize but you will get this message with CardInfo:
You can use the SdFat SdFormatter example to format SDXC cards as FAT32.

The 32 GB card should work.

The SdFat SdInfo example will print hex error codes.

Most likely you will get something like this:

errorCode 0X1 means the SD card is not seen and most likely the card is not the problem since you tried two cards.

This error is caused by an SPI problem such as the wrong chip select for the SD card, not disabling the Ethernet controller, or other wiring/hardware fault. 
fat16lib,

I tried the SdInfo Utility and modified the chip select setting as well in the program.
I tried the default setting of SS, then I tried 4, 8, and 10. They all gave me the same error below:
-------------
SdFat version: 20141111

type any character to start

card.init failed
SD errorCode: 0X1
SD errorData: 0X0

------------

Thanks for the suggestion, I will also try to get another SD card. I don't have the second one on me right now that I tried with before. 


fat16lib

Quote
card.init failed
SD errorCode: 0X1
SD errorData: 0X0
This is rarely the SD card. I get your errorCode and errorData with an Arduino Ethernet shield on an Uno when I set SD_CHIP_SELECT to SS or 10.

You should set SD_CHIP_SELECT to 4.  When I set SD_CHIP_SELECT to 4 with the Arduino Ethernet shield I get success:

Quote
type any character to start

init time: 120 ms

Card type: SDHC

Manufacturer ID: 0X3
OEM ID: SD
Product: SE32G
Version: 8.0
Serial number: 0XF6D24F1
Manufacturing date: 5/2014

cardSize: 31914.98 MB (MB = 1,000,000 bytes)
flashEraseSize: 128 blocks
eraseSingleBlock: true
OCR: 0XC0FF8000

SD Partition Table
part,boot,type,start,length
1,0X0,0XC,8192,62325760
2,0X0,0X0,0,0
3,0X0,0X0,0,0
4,0X0,0X0,0,0

Volume is FAT32
blocksPerCluster: 64
clusterCount: 973584
freeClusters: 973582
freeSpace: 31902.33 MB (MB = 1,000,000 bytes)
fatStartBlock: 9362
fatCount: 2
blocksPerFat: 7607
rootDirStart: 2
dataStartBlock: 24576
When I remove the SD card with SD_CHIP_SELECT set to 4, I get this with the Arduino Ethernet shield:
Quote
SD errorCode: 0X1
SD errorData: 0XFF
Do you get 0XFF for errorData when the card is removed?  Do you get a different value for errorData with the card?

djx18

This is rarely the SD card. I get your errorCode and errorData with an Arduino Ethernet shield on an Uno when I set SD_CHIP_SELECT to SS or 10.

You should set SD_CHIP_SELECT to 4.  When I set SD_CHIP_SELECT to 4 with the Arduino Ethernet shield I get success:

When I remove the SD card with SD_CHIP_SELECT set to 4, I get this with the Arduino Ethernet shield:
Do you get 0XFF for errorData when the card is removed?  Do you get a different value for errorData with the card?
I get the same error with the card removed or inserted in. Both errors are always the same.

As stated earlier i tried setting  SdChipSelect to the default of SS, then 4, 8, and finally tried 10. They all throw the same error below it also doesn't matter if the card is inserted or out its always the same exact error codes. errorCode 0X1 and errorData 0X0

----
SdFat version: 20141111

type any character to start

card.init failed
SD errorCode: 0X1
SD errorData: 0X0
---

fat16lib

Quote
As stated earlier i tried setting  SdChipSelect to the default of SS, then 4, 8, and finally tried 10.
The schematic for the Sainsmart Ethernet card clearly shows that pin 4 is SD chip select.  If SdInfo fails using pin 4, you have a serious hardware problem.

Pin 10 is Ethernet chip select and on an Uno, SdFat sets pin 10 high to disable the Ethernet controller.

If you are not using an Uno, You need this code to disable the Ethernet controller before initializing the SD.
Code: [Select]

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


Again, it is unlikely a third SD card will solve your problem.

djx18

I got fed up and went on bought a real Arduino and Seed Studio ethernet shield from radio shack. Plugged it in and it worked with SdChipSelect = 4 It literally took 30 seconds to get it working with my existing 32GB SD card.

So then I tried plugging the See Studio Ethernet shield into Sainsmart Arduino and that worked too! No issues at all. So the problem comes down to the SainSmart ethernet shield. Now looking closer at this I notice the Seed Studio Arduino ethernet shield has all the pins. The sainsmart ethernet shield is missing 2 pins on the left and 2 pins on the right side. Left pins that are missing are NC and IOREF, Right pins that are missing are SCL and SDA.

As you can see in this picture from their website the shield is missing some pins that plug into the Arduino. 



So the problem is with the SainSmart ethernet shield. Now is there any way of getting this working with those 4 pins missing? Sorry I am a bit of a newbie when it comes to what all the pins do.

fat16lib

Those pins are not used by SdFat or the Ethernet library so you have a bad Ethernet board, as I suspected.

SCL and SDA are duplicate I2C pins and used to provide I2C compatibility with newer shields on Mega and Uno.  Same for the other pins, they are not needed unless you stack another shield that needs them.

Go Up