SD card shield+ethernet.

I recently purchased an arduino uno, a dfrobot ethernet shield and iteadstudio SD card shield. from what i can make out it directly relates to this SPI sharing issue, according to the docs both devices share exactly the same pins, 10, 11, 12 ,13. I can get each device as a standalone working fine but the second i power up the with the ethernet shield on top the SD goes to custard.

I've spent many hours reading an it seems so simle that ... if i shutdown pin 10 with a high signal all should be fine and i can open up the SD card ... but the fact is .. for some reason its NOT working ... i just cannot get that SD card up and running. so its it a hardware fix i am needing or can this be done with software.
Also I think the relevant info re spcecs of each device.
Pin of Arduino With iteadstudio SD Card

Arduino SD Card
5V VCC - 3v3
GND GND
D13 SD_CLK
D12 SD_OUT
D11 SD_IN
D10 SD_CS

dfrobot Ethernet Card w5100
D13 / SCK
D12 / MISO
RESET D11 / MOSI ~
D10 / SS ~

My code is as follows .. seems to work perfectly untill i plug in the ethernet.

/*
SD card datalogger

  • SD card attached to SPI bus as follows:
    ** MOSI - pin 11
    ** MISO - pin 12
    ** CLK - pin 13
    ** CS - pin 10

#include <OneWire.h>
#include <DallasTemperature.h>

// SD card Library
#include <SD.h>
#include <SPI.h>
// CLOCK Library
#include <DS3231.h>
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>

DS3231 Clock;
bool Century=false;
bool h12;
bool PM;
byte ADay, AHour, AMinute, ASecond, ABits;
bool ADy, A12h, Apm;
byte year, month, date, DoW, hour, minute, second;

// SD card
const int chipSelect = 10;

// // Temperature wires connected to Pin 3 on the Arduino (4 sensors in bus configuration)
#define ONE_WIRE_BUS 3
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// relay Digital pin 6
#define RELAY1 6

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

// Assign the addresses of your 1-Wire temp sensors.

DeviceAddress insideThermometer = { 0x28, 0x02, 0xA7, 0xA9, 0x03, 0x00, 0x00, 0xCC };
DeviceAddress outsideThermometer = { 0x28, 0x7E, 0x9F, 0xA9, 0x03, 0x00, 0x00, 0x93 };
DeviceAddress firehotwaterThermometer = { 0x28, 0xBB, 0x73, 0xA9, 0x03, 0x00, 0x00, 0x1C };
DeviceAddress radiatorThermometer = { 0x28, 0xA7, 0x9A, 0xA9, 0x03, 0x00, 0x00, 0x13 };

void setup()
{
//
// disable the ethernet ???
pinMode(10, OUTPUT);
digitalWrite(10, HIGH);

// Open serial communications and wait for port to open:
// Start the I2C interface
Wire.begin();

// set up relay as output

Serial.begin(57600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}

Serial.print("Initializing SD card...");

// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
// don't do anything more:
return;
}
Serial.println("card initialized.");

// Start up the library of temp sensors
sensors.begin();
// set the resolution to 10 bit (good enough?)
sensors.setResolution(insideThermometer, 10);
sensors.setResolution(outsideThermometer, 10);
sensors.setResolution(firehotwaterThermometer, 10);
sensors.setResolution(radiatorThermometer, 10);

}

void printTemperature(DeviceAddress deviceAddress)
{
float tempC = sensors.getTempC(deviceAddress);
if (tempC == -127.00) {
Serial.print("Error getting temperature");
} else {
Serial.print("C: ");
Serial.print(tempC);
//Who Want farenheight!
// Serial.print(" F: ");
// Serial.print(DallasTemperature::toFahrenheit(tempC));
}
}

void loop()
{
Clock.getTime(year, month, date, DoW, hour, minute, second);

// make a string for assembling the data to log:
String dataString = "";

// read three sensors and append to the string:
/*
for (int analogPin = 0; analogPin < 3; analogPin++) {
int sensor = analogRead(analogPin);
dataString += String(sensor);
if (analogPin < 2) {
dataString += ",";
}
}
*/
float tempA;
float tempB;
float tempC;
float tempD;
float tempTEST;
String pumpStatus = "unknown";

Serial.print("Getting temperatures...\n\r");
sensors.requestTemperatures();

tempA = sensors.getTempC(insideThermometer);
tempB = sensors.getTempC(outsideThermometer);
tempC = sensors.getTempC(firehotwaterThermometer);
tempD = sensors.getTempC(radiatorThermometer);

tempTEST = tempC - tempD;

if (int(float(tempTEST > 5))) {

digitalWrite(RELAY1,LOW); // Turns ON Relays 1
pumpStatus = "On";
}
else
{
digitalWrite(RELAY1,HIGH);
pumpStatus = "Off";
}

// open the file. note that only one file can be open at a time, so you have to close this one before opening another.
File dataFile = SD.open("datalog.txt", FILE_WRITE);
// if the file is available, write to it:
if (dataFile) {
// dataFile.println(dataString);
dataFile.print(date, DEC);
dataFile.print("/");
dataFile.print(month, DEC);
dataFile.print("/");
dataFile.print("2");
if (Century) { // Won't need this for 89 years.
dataFile.print("1");
} else {
dataFile.print("0");
dataFile.print(year, DEC);
}
dataFile.print(" ");
dataFile.print(hour, DEC);
dataFile.print(":");
dataFile.print(minute, DEC);
dataFile.print(":");
dataFile.print(second, DEC);
// Start Dumping the Temperatures
dataFile.print(" ");
dataFile.print(tempA);
dataFile.print(" ");
dataFile.print(tempB);
dataFile.print(" ");
dataFile.print(tempC);
dataFile.print(" ");
dataFile.print(tempD);
dataFile.print(" ");
dataFile.println(pumpStatus);
// Close the file
dataFile.close();
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening datalog.txt");
}
// temps to serial port
Serial.print("Inside temperature is: ");
printTemperature(insideThermometer);
Serial.print("\n\r");
Serial.print("Outside temperature is: ");
printTemperature(outsideThermometer);
Serial.print("\n\r");
Serial.print("Fire Water temperature is: ");
printTemperature(firehotwaterThermometer);
Serial.print("\n\r");
Serial.print("Radiator temperature is: ");
printTemperature(radiatorThermometer);
Serial.print("\n\r\n\r");
Serial.print("Temprature Difference:");
Serial.print (tempTEST);
Serial.print("\n\r");
Serial.print("Pump status: ");
Serial.print(pumpStatus);

// print to the serial port too:
Serial.println(dataString);
Serial.print(date, DEC);
Serial.print("/");
Serial.print(month, DEC);
Serial.print("/");
Serial.print("2");
if (Century) { // Won't need this for 89 years.
Serial.print("1");
} else {
Serial.print("0");
}
Serial.print(year, DEC);
//Serial.print("day of the week :");
// Serial.println(DoW, DEC);
Serial.print(" ");
Serial.print(hour, DEC);
Serial.print(":");
Serial.print(minute, DEC);
Serial.print(":");
Serial.println(second, DEC);
Serial.print(" ");
Serial.print(tempA);
Serial.print(" ");
Serial.print(tempB);
Serial.print(" ");
Serial.print(tempC);
Serial.print(" ");
Serial.print(tempD);
Serial.print(" ");
Serial.print(pumpStatus);

// Lets delay before write to the log file again.

delay(30000);
}

... if i shutdown pin 10 with a high signal all should be fine and i can open up the SD card ...

No, it won't be fine. The SD and the w5100 are on the same SS pin (digital pin 10). The devices can share digital pins 11-13, but you must have separate SS pins for each device. That will require some "pin bending" and jumper wires.

Tim,

cheers .. and i think maybe that too .... .... Heres what i have done since posting ...... seperated the shield from plugging in on top of the header pins and on the shield (SD) ... taken pin 10 to pin 4 on the arduino .. and tested it using the following program
and it worked fine .. looks like i have just moved the SD card sucessfully to pin 4 and it works i'm thinking ..... however when i plug the ethernet back into the header pins and take the same pinouts as were just working ie me moving pin 10 to pin 4 the SD shield does not work.. so i added in them lines ... digitalWrite(10,high); thinking maybe i have to still shutdown the ethernet .. i still get no joy.

How much pin bending do i have to do ..? Are there any tutorials do you know ?

I have attached a picture to show you .. basically if i take the ether shield out the SD will work

/*
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; // <<< works untill i plug in the ethernet

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); // <<< I thought disable the ethernet ??
digitalWrite(10,HIGH); // but just the fact its plugged in stops the SD shield from working ... so what pins should i bend.

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

}

On that pic, I see a ground wire, but no power wire. How are you powering the SD card?

the green wire .. comming from + 5 on the left .. excuse the fact that the red wire is actually ground and the green +5 .. but they are there and it does work .. untill the ethernet is also plugged in.

Insure you are disabling the w5100 SPI before initializing the SD. Try the CardInfo sketch in the IDE Examples. There is one thing that causes my SD card to fail in that sketch. In the setup() function:

// this is already there
pinMode(10, OUTPUT); 
// this is not, so add this. My SD card fails the card.init() call if I don't.
digitalWrite(10,HIGH);

Tim,

Cardinfo looks like this see code below. . Note them lines are there ....
pinMode(10, OUTPUT);
digitalWrite(10, HIGH);

/*
  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;    // I have changed this from pin 10  (as per photo) and tested the SD card and it works untill i plug in the ethernet shield

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);     // 
  digitalWrite(10, HIGH);

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

but it does not work .. unless i i take out the ethernet shield

The only other thing I can think of is try another pin besides digital 4 for the SD SS. Try it on digital pin 9. Change the sketch chipSelect variable to 9.

tim,

thanks for your help .. for the record I tried pin 9 and the SD card still failed ..

I unplugged the ethernet card as per pic (still left CS attached to 9 and the SD card works ... I'm not sure what to try next.

It sounds like the w5100 is not releasing one of the SPI lines.

Can you connect the SD card to the arduino, then connect the ethernet shield into the SD card? If so, try "pin bending" digital pins 10, 11, 12, and 13 on the ethernet shield so they do not insert into the SD card. Try the CardInfo sketch again. If that works, try inserting each pin one at a time back into the SD card until it fails.

edit: You must do a bit of pin bending and jumpering to do that. It may not be feasible to try that. You must jumper digital 10 from the ethernet shield to the arduino, and jumper digital 10 on the SD to digital 4 or 9 on the arduino. :astonished:

Maybe it would be best to connect the ethernet shield to the arduino with digital pins 11-13 bent. Connect the SD card to the arduino with the screw terminals. That is what I am seeing, correct?