4
\$\begingroup\$

In an answer Kevin Mark points to a solution/reason for the usage of the Ethernet shield together with the SD Card. The documentation says that SD Card and the Ethernet chip both share the SPI bus and that I have to set different pins on HIGH to tell the Ethernet shield to use the Ethernet OR the SD Card.

How would such a solution look like?

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

// Now I can use the SD Card?

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

// Now I can use the Ethernet (W5100)?

// Do I have to (re)set 4 to LOW?
// Any possibility to use both at the same time?
// Can I use the Ethernet/SD Card without the setting of pin 4 or 10?
// Why is this missing on the official code examples? Is it really necessary?
\$\endgroup\$

3 Answers 3

8
\$\begingroup\$

In SPI, the following connections are used:

  • MISO (Master In Slave Out) - a data line for sending data from the slave to the master
  • MOSI (Master Out Slave In) - a data line for sending data from the master to the slave
  • SCK (Serial Clock) - a clock generated by the master for clocking the bits on MISO and MOSI
  • SS (Slave Select) - a data line from the master to a particular slave.

There is one SS for every slave device. MISO, MOSI, and SCK are shared between all the devices on the bus.

In your case, pin 4 is SS for the SD card interface while pin 10 is SS for the ethernet controller.

Your code should look something like this (untested code):

#define SS_SD_CARD   4
#define SS_ETHERNET 10

void setup() {
    // ...
    pinMode(SS_SD_CARD, OUTPUT);
    pinMode(SS_ETHERNET, OUTPUT);
    digitalWrite(SS_SD_CARD, HIGH);  // SD Card not active
    digitalWrite(SS_ETHERNET, HIGH); // Ethernet not active
    // ...
}

void scCardCode() {
    // ...
    digitalWrite(SS_SD_CARD, LOW);  // SD Card ACTIVE
    // code that sends to the sd card slave device over SPI
    // using SPI.transfer() etc.
    digitalWrite(SS_SD_CARD, HIGH); // SD Card not active
    // ...
}

void ethernetCode() {
    // ...
    digitalWrite(SS_ETHERNET, LOW);  // Ethernet ACTIVE
    // code that sends to the ethernet slave device over SPI
    // using SPI.transfer() etc.
    digitalWrite(SS_ETHERNET, HIGH); // Ethernet not active
    // ...
}

You should make sure that 4 and 10 are not low at the same time because that would cause the same data to be sent to both slaves--BAD.

Your library probably handles setting 4 & 10 low and high at the appropriate times. However, there may be methods that leave one of them low until another method sets it high. During that period, you should not use a method for the other device. It's possible for the library to handle cases like this, but since your bug seems to be known, it obviously does not do it well, if at all.

\$\endgroup\$
2
  • \$\begingroup\$ Thank you a lot! But I'm still surprised that on the official code examples there is NO hint about this! \$\endgroup\$
    – powtac
    Commented Apr 19, 2013 at 8:57
  • \$\begingroup\$ Thanks for this post. After struggling for two hours trying to get my official Arduino Ethernet shield to access its SD card when mounted on a MEGA 2560, I did the digitalWrite (53,HIGH); and it worked. Why in the world don't they fix that in the examples? Anyway, thank you again. \$\endgroup\$
    – Jim Sky
    Commented Dec 21, 2014 at 3:29
3
\$\begingroup\$

This adafruit wiki page seems to have a decent example.

The only reference I see to the pin 4 and 10 stuff in the code is setting pin 10 to HIGH once on init.

pinMode(10, OUTPUT);      // set the SS pin as an output (necessary!)
digitalWrite(10, HIGH);   // but turn off the W5100 chip!

I assume the Ethernet and SD card libraries handle it from there. Be sure to check out that entire page.

\$\endgroup\$
2
\$\begingroup\$

There is a hint on http://arduino.cc/en/Main/ArduinoEthernetShield

Note that because the W5100 and SD card share the SPI bus, only one can be active at a time. If you are using both peripherals in your program, this should be taken care of by the corresponding libraries. If you're not using one of the peripherals in your program, however, you'll need to explicitly deselect it. To do this with the SD card, set pin 4 as an output and write a high to it. For the W5100, set digital pin 10 as a high output.

The above answer solves the problem but there are no examples on the standard libraries how to use both functions in order to use Ethernet and SD for Datalogging as an example.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.