SD Card Shield configuration on Arduino mega 2560 REV3?

Hello,

I'm new to the world of arduino, sorta. I have two Arduinos, an Uno REV2, and the Mega REV3. I bought the Mega thinking I would be able to carry my SD Card Shield (Seeedstudio 3.0 I believe) to work on my new Mega. Once I got home, I thought, okay, I'll align the pins accordingly, did that, got a "initialization failed!" from the ReadWrite example for SD Cards (It works on my Uno just fine). I then read that I have to attatch pins 11,12,13 to Mega's 50,51,52, did that, and then attatch the SS pin, which on the Uno is pin 10, to the Mega's pin 53. Did that, and I still get an "initialization failed!". I connected the 4 pins (11-50,12-51,13-52 and 10-53) via standard jumpers. My setup:

SD Card Shield is attached to Uno.
Connected the pins as this page says (http://arduino.cc/de/Reference/SD)
Pins were: 11-50,12-51,13-52 and 10-53
Once the Arduino Uno was plugged in and powering, aswell as the Mega, and opened the ReadWrite and launched the program, making sure the "Mega 2560 or Mega ADK" board was selected, and the serial port was correct (For me, COM4).

CODE:

/*
  SD card read/write
 
 This example shows how to read and write data to and from an SD card file 	
 The circuit:
 * SD card attached to SPI bus as follows:
 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK - pin 13
 ** CS - pin 4
 
 created   Nov 2010
 by David A. Mellis
 modified 9 Apr 2012
 by Tom Igoe
 
 This example code is in the public domain.
 	 
 */
 
#include <SD.h>

File myFile;

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("Initializing 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(53, OUTPUT);
   
  if (!SD.begin(53)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
  
  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  myFile = SD.open("test.txt", FILE_WRITE);
  
  // if the file opened okay, write to it:
  if (myFile) {
    Serial.print("Writing to test.txt...");
    myFile.println("testing 1, 2, 3.");
	// close the file:
    myFile.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }
  
  // re-open the file for reading:
  myFile = SD.open("test.txt");
  if (myFile) {
    Serial.println("test.txt:");
    
    // read from the file until there's nothing else in it:
    while (myFile.available()) {
    	Serial.write(myFile.read());
    }
    // close the file:
    myFile.close();
  } else {
  	// if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }
}

void loop()
{
	// nothing happens after setup
}

I still received the "initialization has failed!" error in the Serial Monitor. Ideas?

Thank you.

SOLUTION: After reading the Seeedstudio wiki on their SD Card Shield, it appears that either they've designed their shield differently, or Arduino's SD Reference is messed up.

PIN CORRECTION:
11>50
12>51
13>52
4 OR 10>53

Is there a difference between 11-50 and 11 > 50? If so, how does one wire 11 > 50 as opposed to 11-50?

There's no difference between 11-50 and 11>50. I used 11-50 when stating you connect pin 11 to pin 50, and later for some reason switched to the > instead. My bad! D:

Is it possible to use the Micro SC breakout board, with headers on a Mega 2560 with pins 10 - 13, instead of 50 - 53?
i.e. how to I "re-map" the pins on the Mega 2560 to be the same as the UNO, in order to fit this breakout board when the header pins are already soldered onto it?

NoahDavis:
SOLUTION: After reading the Seeedstudio wiki on their SD Card Shield, it appears that either they've designed their shield differently, or Arduino's SD Reference is messed up.

PIN CORRECTION:
11>50
12>51
13>52
4 OR 10>53

The SS pin on the Uno is pin 10, however the code in the sample sketch allows you to use another pin, such as pin 4. It also states that regardless of what other pin you're using, pin 10 is still used and needs to be set as an OUTPUT. If you adjusted the code to use pin 10 (SS) instead of 4, if should work. Pin 4 is just an alternative pin because the Arduino Ethernet shield uses the SPI port, which are pins 10, 11, 12, and 13, so the built-in SD card reader needed to go elsewhere and they picked pin 4. If you don't have anything on the SPI port, you can use pin 10 (SS) instead of 4.

The Arduino SPI pins are:

SPI Uno Mega
SS 10 53
MOSI 11 51
MISO 12 50
SCK 13 52

So:
11>51
12>50
13>52

Any pin can be used for SD chip select.

  SD.begin(CS_PIN);

For more see SPI - Arduino Reference.

This is yet another cheap SD card shield/module. There is no logic level shifter, just resistors. And the SPI pins are hardwired to Arduino pins 10-13. If you want to use this shield on MEGA without rewiring, you can enable the software SPI mode in the SD library.

Instruction here:

Make sure this line in the SD.h file is not commented to enable software spi

#define MEGA_SOFT_SPI 1

Hi Guys,

I'm having similar issues. I'm using a MEGA ADK and the Arduino WiFi shield to log data to the SD card - not actually using the WiFi function of the shield.

For some reason I can't detect the SD card. I have tried several SD cards and starting to think it is an issue with the MEGA ADK. I have two of these boards and dosnt work on either of them.

The same WiFi shield and SD cards work fine on my DUE board but need it to work on my MEGA. I use the following code.

// libraries used
#include <Debounce.h>
#include <SPI.h>
#include <SD.h>
#include <math.h> // math library not imported by default

/*
THIS IS A HACK setting the ADC prescale to 16 for faster analog read speed.
C function used:
sbi() "clear the bits"
cli() "set the bit"
C variables use in the source code use during complie time
srb "shift register name" sketch variable
bit "address of the register in bits" sketch variable
_SFR_BYTE() "shift register name" dummy variable to access the source code
_BV() "address of the register in bits" dummy variable to access the source code
*/
#ifndef cbi
#define cbi(sfr,bits) (_SFR_BYTE(sfr) &= ~_BV(bits))
#endif
#ifndef sbi
#define sbi(sfr,bits) (_SFR_BYTE(sfr) |= _BV(bits))
#endif

// constant variables before compile
#define stopSwitch 48 // stop switch connected to pin 48

// create instances of the classes included in the libraries
Debounce debouncer1=Debounce(20,stopSwitch);

// declare global constants and their data types
const float deltaVolts=5.0/pow(2,10); // 5.0 volts input divided by the 2^10 (MEGA) or 2^12 (DUE) ADC i.e. 12 bits of resolution

// declare global variables and their data types
int sensorValue;
int id=1;
float volts;

// declare files
File dataFile;

// setup code here, to run once
void setup() 
{
  //analogReference(DEFAULT);                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
  Serial.begin(115200); // initialize serial communication
  while(!Serial)
  {
  }
  Serial.print("Initializing SD card..."); // print to the serial monitor a message
  pinMode(53,OUTPUT); // pin 53 must be left as an OUTPUT for the SD library to work
  pinMode(10,OUTPUT); // pin 10 must be left as an OUTPUT so it can be set HIGH
  digitalWrite(10,HIGH); // pin 10 needs to be put HIGH to explicitly deselect the WiFi HDG104 chip
  pinMode(stopSwitch,INPUT);
  digitalWrite(stopSwitch,LOW);
  if(!SD.begin(4)) // Chip Select pin 4 default channel on WiFi sheild for SD communication. If the statement !SD.begin(SS) comes back as FALSE execute the "if" statement
  {
    Serial.println("Card failed or not present"); // print to screen the SD card status
    return; // start the loop again and check if the SD is faulty or not installed
  }
  else
  {
    Serial.println("Card initialized"); // else everything is all good
  }
  if(SD.exists("volts.csv"))
  {
    Serial.println("File exists and now being removed");
    SD.remove("volts.csv");
  }
  else
  {
    Serial.println("No file could be found");
  }
  Serial.print("Sample No.");
  Serial.print(",");
  Serial.println("Volts");
  dataFile=SD.open("volts.csv",FILE_WRITE);
  dataFile.print("Sample No.");
  dataFile.print(",");
  dataFile.println("Volts");
  dataFile.close();
  //analogReadResolution(12); // default resolution is 10 bit statment changes to 12 bit for the DUE board but line not use when using the MEGA or low boards
}

// main code
void loop() 
{
  debouncer1.update(); // update the debouncer
  sensorValue=analogRead(A0);
  volts=deltaVolts*sensorValue;
  dataFile=SD.open("volts.csv",FILE_WRITE);
  if(dataFile && debouncer1.read()==LOW)
  {
    dataFile.print(id,DEC);
    dataFile.print(",");
    dataFile.println(volts,DEC);
    dataFile.close();
    Serial.print(id,DEC);
    Serial.print(",");
    Serial.println(volts,DEC);
    float jam=log10(volts);
  }
  else
  {
    dataFile.close();
    return;
  }
  id++;
}

But keeps stopping at

if(!SD.begin(4))

on my ADK.

Any help would be much appreciated.

What is stopWatch pin? Its pin number?

Which SD library are you using, the adafruit SD library or the arduino IDE SD library? Do you have an SD library from adafruit on your computer? There is a version of adafruit SD library that can use software SPI on pins 11-13 to save their areses for their SD logger shield but you should NOT use software SPI.

Hi Liudr,

Sorry for not getting back to your reply sooner. Only starting to learn the functionality of this forum i.e. didn't know how too keep track of replies etc.

I have solved the issue. I needed to deselect the WiFi chip by setting it hig as per the following code.

pinMode(10,OUTPUT); // pin 10 must be left as an OUTPUT so it can be set HIGH
  digitalWrite(10,HIGH); // pin 10 needs to be put HIGH to explicitly deselect the WiFi HDG104 chip[code]

To answer your question I'm just using the Arduino SD library.

Thanks for the reply.

Cheers

Adam

[/code]

I have the same problem, pins are right for mega 2560

50 51 52 and ss is 53, but it still doesn't work on the mega2560

thanks for the #7 liudr replay . the sd library which has recommended is worked very well

thanks a lot again !

Maybe the original sd library has some problems to support mega, i guess. but I have tried uno and leonardo. it is fine.

liudr:
This is yet another cheap SD card shield/module. There is no logic level shifter, just resistors. And the SPI pins are hardwired to Arduino pins 10-13. If you want to use this shield on MEGA without rewiring, you can enable the software SPI mode in the SD library.

Instruction here:

Older Datalogger Shield Leonardo & Mega Library | Adafruit Data Logger Shield | Adafruit Learning System

Make sure this line in the SD.h file is not commented to enable software spi

#define MEGA_SOFT_SPI 1

I don't find the code that site refer to.
Could anyone tell me the file and the lines to find this piece of code?
Also the library that exixt in the link is not compaling and for this reason i have this message:
[C:\Users?????\Documents\Arduino\libraries\SD\utility\Sd2Card.cpp: In member function 'uint8_t Sd2Card::init(uint8_t, uint8_t, int8_t, int8_t, int8_t)':
C:\Users?????\Documents\Arduino\libraries\SD\utility\Sd2Card.cpp:290: error: 'digitalPinToPort' was not declared in this scope
C:\Users?????\Documents\Arduino\libraries\SD\utility\Sd2Card.cpp:290: error: 'portOutputRegister' was not declared in this scope
C:\Users?????\Documents\Arduino\libraries\SD\utility\Sd2Card.cpp:291: error: 'digitalPinToBitMask' was not declared in this scope
C:\Users?????\Documents\Arduino\libraries\SD\utility\Sd2Card.cpp:294: error: 'portInputRegister' was not declared in this scope]

Big blue button that says down this library. Once you install it in the correct folder, restart arduino IDE and try again.

liudr:
Big blue button that says down this library. Once you install it in the correct folder, restart arduino IDE and try again.

And then do I have anything else to do to work on arduino MEGA? For examble, do ihave to change any piece of code?

Yes you do. I just did this and got it to work. Read the article from the linky above and it will guide you through what you need to do. you have to change the (10, 11, 12, 13) pins to the ones listed in the chart at the beginning of this thread for the Mega.

Dom

Hi,
I am here with the same problems: an Arduino Mega 2560 and a Ethernet shield, trying to read a SD card.

It simply stops at SD.begin();

I've tryed to install the Adafruit modified SD library, but nothing changed, I tryed all sorts of combination of the OUTPUT pin and chipSelect pin.
It seems strange to me that the Ethernet shield is sold as fully compatible with the Mega board and then you have to install an Adafruit library that doesn't work neither.

What should i try? To wire the shield by hand with default SPI Mega pins (51, 52, 53)?

Thank you!

olimex,

If you have an Arduino Ethernet shield, it should work with the standard SD library. You need to disable the W5100 with these lines before calling SD.begin();

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

Try CardInfo after changing this:

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

To This:

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

Ignore the comments about pin 53. The comments are wrong.

Leave SD chip select as pin 4:

const int chipSelect = 4;

Don't try to use the Adafruit library. It won't work with the Ethernet shield on Mega.

Hey man, you can't imagine how much I love you!

Thanks, Luca from Italy!

Hey all,

I am having a similar problem. I am using a Mega with the adafruit logger. I was going to try using the Soft SPI so I didn't have to make the wiring changes. I was reading on another post

http://forum.arduino.cc/index.php?PHPSESSID=tt4r951a3kmj4i3nttskohhbq3&topic=63018.0

I tried making the changes to the SD2Card.h file to enable the Soft SPI but I keep getting the following error.

Compiling 'CardInfo' for 'Arduino Mega 2560 or Mega ADK'
Sd2Card.cpp:In member function 'uint8_t Sd2Card::setSckRate(uint8_t)'
Sd2Card.cpp:585: error: 'SPI' was not declared in this scope
Error compiling

I am just trying to use the card info example to see the card there but I keep getting the card not initialized message.
Heres the code I am using:

/*
  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:
 ** UNO:  MOSI - pin 11, MISO - pin 12, CLK - pin 13, CS - pin 4 (CS pin can be changed)
  and pin #10 (SS) must be an output
 ** Mega:  MOSI - pin 51, MISO - pin 50, CLK - pin 52, CS - pin 4 (CS pin can be changed)
  and pin #52 (SS) must be an output
 ** Leonardo: Connect to hardware SPI via the ICSP header
 		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 = 10;    

void setup()
{
 // Open serial communications and wait for port to open:
  Serial.begin(115200);
   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);


  // we'll use the initialization code from the utility libraries
  // since we're just testing if the card is working!
  while (!card.init(SPI_HALF_SPEED, SD.begin(10,11,12,13))) {
    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?");
  } 
  
  // 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) {
  
}

This is where the error takes me in the Sd2Card.cpp file:

#ifdef SPI_CLOCK_DIV128
  switch (sckRateID) {
    case 0: v=SPI_CLOCK_DIV2; break;
    case 1: v=SPI_CLOCK_DIV4; break;
    case 2: v=SPI_CLOCK_DIV8; break;
    case 3: v=SPI_CLOCK_DIV16; break;
    case 4: v=SPI_CLOCK_DIV32; break;
    case 5: v=SPI_CLOCK_DIV64; break;
    case 6: v=SPI_CLOCK_DIV128; break;
  }
#else // SPI_CLOCK_DIV128
  v = 2 << sckRateID;
#endif // SPI_CLOCK_DIV128
 ------> [b] SPI.setClockDivider(v);[/b]
#endif // USE_SPI_LIB
  return true;
}

I am using the SD.h and SD.cpp files from the adafruit website :

I thought I had done everything that the post told me to but apparently I have not. Please let me know if you see the mistake. I appreciate your time.