HELP: Ethernet+SD: As soon as use Ethernet, SD refuses to open files

Hello, I am really frustrated, have check around 10 sketches on the net. Think I do understand usage of the SPI bus and the meaning of SS/CS.

The problem boils down to: As soon as I check for available ethernet data, the SD lib refuses to open files. What needs to be done? Please.. can anyone help?! :~

Here is the code:

#include <SPI.h>
#include <SD.h>
#include <Ethernet.h> // Tested in version IDE 0022 Arduino UNO
#include <EthernetUdp.h> 

byte myMac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xB4, 0xCB  };//the mac adress of ethernet shield or uno shield board
byte myIp[] = { 10,0,0,250 };// the IP adress of your device, that should be in same universe of the network you are using, here: 192.168.1.x
int  listenPort  = 6455;           //   listen here for OSC (incomming)

File myFile;
EthernetUDP Udpin;

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(115200);

  // B): --------- Start Ethernet -----------------
  Ethernet.begin(myMac ,myIp);
  Serial.println("Open Port to listen for incomming OSC packages"); 
  Udpin.begin(listenPort);
  
  // A): --------- Init SD card -----------------
  Serial.print("Initializing SD card...");
  pinMode(10, OUTPUT);

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

void loop()
{  

  Serial.println("--------- Loop begin -----------");

  // C): --------- Read File ----------------- 
  myFile = SD.open("test3.txt");
  if (myFile) {
    Serial.println("test3.txt:");
    // read from the file until there's nothing else in it:
    while (myFile.available()) {
      Serial.write(myFile.read());
    }
    // close the file:
    myFile.close();
    Serial.println("- EOF -");
  } 
  else {
    // if the file didn't open, print an error:
    Serial.println("Read: error opening test2.txt");
  }
  // nothing happens after setup finishes.
  delay(2000);
  
  // D): --------- Check for packets arrived ----------------
  int packetSize = Udpin.parsePacket();
  if(packetSize){
    Serial.print("Packet recieved..");  
  };

  delay(1000);
}

Here is the output. As you can see the first time the code runs the file is found and read.
.. but then I check for available ethernet data. And then - on the next cycle - the SD lib cannot open the file anymore.

Open Port to listen for incomming OSC packages
Initializing SD card...initialization done.
done!
--------- Loop begin -----------
test3.txt:
22.22.--------- Loop begin -----------
Read: error opening test2.txt
--------- Loop begin -----------
Read: error opening test2.txt
--------- Loop begin -----------
Read: error opening test2.txt
..

If I take out the ethernet code from the main loop (block D). The the file is continously read correctly.

If I change the order of the code (swap C / D) - meaning first check for data arrived and then access the SD card, it fails immediately..

What can I do? I guess it is something about SPI and switching between the devices, but what.

I am using a Arduino UNO (R3) + the standard Ethernet Shield with WS5100. I compile with Arduino 1.0.5 and only use the standard libraries.

Jens

    Serial.println("test3.txt:");
    // read from the file until there's nothing else in it:
    while (myFile.available()) {
      Serial.write(myFile.read());
    }
    // close the file:
    myFile.close();
    Serial.println("- EOF -");

In your output, I do not see "- EOF -".

You should investigate why that doesn't appear.

  int packetSize = Udpin.parsePacket();
  if(packetSize){

packetSize is not a boolean. Do not use it as one.

Server test code that down loads a file to a browser from the SD card.

//zoomkat 12/26/12
//SD server test code
//open serial monitor to see what the arduino receives
//address will look like http://192.168.1.102:84 when submited
//for use with W5100 based ethernet shields

#include <SD.h>
#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 
  192, 168, 1, 102 }; // ip in lan
byte gateway[] = { 
  192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 
  255, 255, 255, 0 }; //subnet mask
EthernetServer server(84); //server port
String readString; 

//////////////////////

void setup(){

  Serial.begin(9600);

  // disable w5100 while setting up SD
  pinMode(10,OUTPUT);
  digitalWrite(10,HIGH);
  Serial.print("Starting SD..");
  if(!SD.begin(4)) Serial.println("failed");
  else Serial.println("ok");

  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  //delay(2000);
  server.begin();
  Serial.println("Ready");
}

void loop(){
  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {
          //store characters to string 
          readString += c; 
          //Serial.print(c);
        } 
        //if HTTP request has ended
        if (c == '\n') {

          ///////////////
          Serial.println(readString); //print to serial monitor for debuging 

            client.println("HTTP/1.1 200 OK"); //send new page
          //client.println("Content-Type: text/html");
          client.println("Content-Type: image/jpeg");
          //client.println("Content-Type: image/gif");
          //client.println("Content-Type: application/x-javascript");
          //client.println("Content-Type: text");

          client.println();

          //File myFile = SD.open("boom.htm");
          File myFile = SD.open("HYPNO.JPG");
          //File myFile = SD.open("BLUEH_SL.GIF");
          //File myFile = SD.open("SERVOSLD.HTM");

          if (myFile) {

            byte clientBuf[64];
            int clientCount = 0;

            while(myFile.available())
            {
              clientBuf[clientCount] = myFile.read();
              clientCount++;

              if(clientCount > 63)
              {
                // Serial.println("Packet");
                client.write(clientBuf,64);
                clientCount = 0;
              }
            }
            //final <64 byte cleanup packet
            if(clientCount > 0) client.write(clientBuf,clientCount);            
            // close the file:
            myFile.close();
          }
          delay(1);
          //stopping client
          client.stop();
          readString="";
        }
      }
    }
  } 
}

HEy.. sorry.. thanks for helping. The "EOF" was not in the log because I posted the wrong log (my mistake).. Here the correct one:

zÿOpen Port to listen for incomming OSC packages
Initializing SD card...initialization done.
done!
--------- Loop begin -----------
test3.txt:
22.22.- EOF -
--------- Loop begin -----------
Read: error opening test2.txt
--------- Loop begin -----------
Read: error opening test2.txt
--------- Loop begin -----------
Read: error opening test2.txt

So it is in.. I took the boolean test from a sketch I found on the internet.

Will now check the web server test.

Just checked the webserver example. Does not work in my case.

Here the (adapted) sketch. Replaced IP and added a Serial.print:

//for use with W5100 based ethernet shields

#include <SD.h>
#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xB4, 0xCB  }; //physical mac address
byte ip[] = { 10,0,0,250 }; // ip in lan
byte gateway[] = { 10,0,0,1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
EthernetServer server(84); //server port
String readString; 

//////////////////////

void setup(){

  Serial.begin(115200);

  // disable w5100 while setting up SD
  pinMode(10,OUTPUT);
  digitalWrite(10,HIGH);
  Serial.print("Starting SD..");
  if(!SD.begin(4)) Serial.println("failed");
  else Serial.println("ok");

  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  //delay(2000);
  server.begin();
  Serial.println("Ready");
}

void loop(){
  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    Serial.print("request!");
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {
          //store characters to string 
          readString += c; 
          //Serial.print(c);
        } 
        //if HTTP request has ended
        if (c == '\n') {

          ///////////////
          Serial.println(readString); //print to serial monitor for debuging 

            client.println("HTTP/1.1 200 OK"); //send new page
          //client.println("Content-Type: text/html");
          client.println("Content-Type: image/jpeg");
          //client.println("Content-Type: image/gif");
          //client.println("Content-Type: application/x-javascript");
          //client.println("Content-Type: text");

          client.println();

          //File myFile = SD.open("boom.htm");
          File myFile = SD.open("HYPNO.JPG");
          //File myFile = SD.open("BLUEH_SL.GIF");
          //File myFile = SD.open("SERVOSLD.HTM");

          if (myFile) {

            byte clientBuf[64];
            int clientCount = 0;

            while(myFile.available())
            {
              clientBuf[clientCount] = myFile.read();
              clientCount++;

              if(clientCount > 63)
              {
                // Serial.println("Packet");
                client.write(clientBuf,64);
                clientCount = 0;
              }
            }
            //final <64 byte cleanup packet
            if(clientCount > 0) client.write(clientBuf,clientCount);            
            // close the file:
            myFile.close();
          }
          delay(1);
          //stopping client
          client.stop();
          readString="";
        }
      }
    }
  } 
}

I put a icon JPG on the SD disk. Named it HYPNO.JPG.

I open a browser and type "10.0.0.250" (Enter).. and the browser runs until it times out. (So I asume the Arduino does not send back any data). The line "Request!" does not get processed. Why is that?!

I do not understand.. Could it be that my shield is bad or the SD card..?!

I am using the official 1.0.5. With the original libraries provided.
My Arduino is a UNO R3 (SMD) , the SD card is 256MB, the Ethernetshield is the common Ethernetshield from Arduino.

I use a Mac, all devices connected to one network (10.0.0.x)

I am clueless :-((

Wrong port to use the ip by itself. Open a browser and type "10.0.0.250:84" (Enter).

Or use the correct port.

// change this line
EthernetServer server(84); //server port
// to this
EthernetServer server(80); //server port

Ok thanks... I DOES NOT WORK :frowning:

My Code looks like this now:

//for use with W5100 based ethernet shields

#include <SD.h>
#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xB4, 0xCB  }; //physical mac address
byte ip[] = { 10,0,0,250 }; // ip in lan
byte gateway[] = { 10,0,0,1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
EthernetServer server(84); //server port
String readString; 

//////////////////////

void setup(){

  Serial.begin(115200);

  // disable w5100 while setting up SD
  pinMode(10,OUTPUT);
  digitalWrite(10,HIGH);
  Serial.print("Starting SD..");
  if(!SD.begin(4)) Serial.println("failed");
  else Serial.println("ok");

  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  //delay(2000);
  server.begin();
  Serial.println("Ready");
}

void loop(){
  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    Serial.print("request!");
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {
          //store characters to string 
          readString += c; 
          ////Serial.print(c);
        } 
        //if HTTP request has ended
        if (c == '\n') {

          ///////////////
          Serial.println(readString); //print to serial monitor for debuging 
          Serial.println("Reply:");
          client.println("HTTP/1.1 200 OK"); //send new page
          client.println("Content-Type: text/html");
         // client.println("Content-Type: image/jpeg");
          //client.println("Content-Type: image/gif");
          //client.println("Content-Type: application/x-javascript");
          //client.println("Content-Type: text");

          client.println();

          //File myFile = SD.open("boom.htm");
          File myFile = SD.open("INDEX.HTM");
          //File myFile = SD.open("INDEX.HTM");
          //File myFile = SD.open("SERVOSLD.HTM");

          if (myFile) {
            
            byte clientBuf[64];
            int clientCount = 0;

            while(myFile.available())
            {
              clientBuf[clientCount] = myFile.read();
              clientCount++;

              if(clientCount > 63)
              {
                Serial.println("Packet");
                client.write(clientBuf,64);
                clientCount = 0;
              }
           }
            //final <64 byte cleanup packet
            if(clientCount > 0) client.write(clientBuf,clientCount);            
            //close the file:
            myFile.close();
          }
          else
          {
            Serial.println("Could not open file.");
          }
          delay(1);
          //stopping client
          client.stop();
          readString="";
        }
      }
    }
  } 
 delay(1000);
}

When I access 10.0.0.25:84 on my browser I get the following response: (Serial console)

ÿStarting SD..ok
Ready
request!GET / HTTP/1.1

Reply:
Could not open file.

So the arduino got the request, but it could not open the file. (Which is exactly is the symptoms I am dealing since many hours.) I am really deperate.

If I do NOT initalize ethernet (and just look for the file):
New code:

//for use with W5100 based ethernet shields

#include <SD.h>
#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xB4, 0xCB  }; //physical mac address
byte ip[] = { 10,0,0,250 }; // ip in lan
byte gateway[] = { 10,0,0,1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
//EthernetServer server(84); //server port
String readString; 

//////////////////////

void setup(){

  Serial.begin(115200);

  // disable w5100 while setting up SD
  pinMode(10,OUTPUT);
  digitalWrite(10,HIGH);
  Serial.print("Starting SD..");
  if(!SD.begin(4)) Serial.println("failed");
  else Serial.println("ok");

//x  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  //delay(2000);
//x  server.begin();
  Serial.println("Ready");
}

void loop(){
  // Create a client connection
//x  EthernetClient client = server.available();
//x  if (client) {
    Serial.print("request!");
//x    while (client.connected()) {
 //x     if (client.available()) {
   //x     char c = client.read();

        //read char by char HTTP request
    //x    if (readString.length() < 100) {
          //store characters to string 
       //x   readString += c; 
          ////Serial.print(c);
      //x  } 
        //if HTTP request has ended
    //x    if (c == '\n') {

          ///////////////
          Serial.println(readString); //print to serial monitor for debuging 
          Serial.println("Reply:");
    //x      client.println("HTTP/1.1 200 OK"); //send new page
    //x      client.println("Content-Type: text/html");
         // client.println("Content-Type: image/jpeg");
          //client.println("Content-Type: image/gif");
          //client.println("Content-Type: application/x-javascript");
          //client.println("Content-Type: text");

    //x      client.println();

          //File myFile = SD.open("boom.htm");
          File myFile = SD.open("INDEX.HTM");
          //File myFile = SD.open("INDEX.HTM");
          //File myFile = SD.open("SERVOSLD.HTM");

          if (myFile) {
            
     //x       byte clientBuf[64];
     //x       int clientCount = 0;

      //x      while(myFile.available())
      //x      {
      //x        clientBuf[clientCount] = myFile.read();
      //x        clientCount++;

      //x        if(clientCount > 63)
      //x        {
      //x          Serial.println("Packet");
      //x          client.write(clientBuf,64);
      //x          clientCount = 0;
      //x        }
      //x     }
            //final <64 byte cleanup packet
      //x      if(clientCount > 0) client.write(clientBuf,clientCount);            
            //close the file:
            myFile.close();
          }
          else
          {
            Serial.println("Could not open file.");
          }
          delay(1);
          //stopping client
      //x    client.stop();
          readString="";
   //x     }
   //x   }
  //x  }
 //x } 
 delay(1000);
}

The result: It continously can open the file:

Starting SD..ok
Ready
request!
Reply:
request!
Reply:
request!
Reply:
request!
Reply:
request!
Reply:
request!
Reply:
request!
Reply:
request!
Reply:

Now you can see that there is still a problem.
What is wrong her?! I appreciate any help... Might the ethernet shield be defect or the SD card incompatible?

Since that code does not actually read from the file, or print any kind of error messages, you've proven nothing.

I haven't inspected the SD or Ethernet libraries, but if either of them left slave select active then that would interfere with SPI communications to the other device. So I suggest you focus on your original idea of understanding which pin each device is using for SS, and look at the source for the libraries you're using to see what they are each doing with their respective SS.

Also check whether either library is changing the SPI configuration (bit order, speed, data mode).

Thanks, I will try.. unfortunatly I a, newbee to Arduino.. so difficult for me to find the problem..

I would love to find an example sketch that just works. The standard Ethernet+SD shield together is not such an strange combination.

I would love to find an example sketch that just works. The standard Ethernet+SD shield together is not such an strange combination.

The code I posted works with arduino my setup. Something must be different in your setup. Your arduino connected to a router? Where did you get the below values you are using?

byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xB4, 0xCB  }; //physical mac address
byte ip[] = { 10,0,0,250 }; // ip in lan
byte gateway[] = { 10,0,0,1 }; // internet access via router

These settings are:

  • The MAC address as printed on the ethernet shield (double checked)
  • The gateway (10.0.0.1) of the network the Arduino is connected to (It is directly connected to the router. I work with with fixed IP addresse,.. and that one is definitly not already assigned to something else)

No it does not work for me. I double-checked.

I was fine working with Ethernet on some of my other project, but as soon as I tried to utilize the SD part it failed.

As your code runs fine. What be the sources of the problem?

The Arduino is UNO Rev 3 (SMD version) from around April/May this year.
Same for the Ethernet shield with WS5001
The SD card is a micro SD, 256MB

I also checked out to different power supplies.

The software is the official 1.0.5 which I downloaded just a couple of days before...

I am clueless... Next I will try different cards, see if there is a difference.. Is there anything else I can check?!

Thanks, anyway.

The Arduino is UNO Rev 3 (SMD version) from around April/May this year.
Same for the Ethernet shield with WS5001
The SD card is a micro SD, 256MB

You have a different setup from mine. I have an Ethernet shield with the W5100 chip and built in SD slot.

No sorry zoomkat... mine is also a WS5100. (Typing mistake)
I checked on the chip. And the SD card is on it as well.

In other words: I have the most common most basic setup.

What else?

  • SD card defect/not fully operational?
  • Shield defect?
  • Something wrong with arduino IDE 1.0.5 and standard libraries? (Note: I run the Mac/OSX port of the IDE)

The thing is: If I disable the Ethernet code in the sketch SD runs just fine. I must have to do with the SPI and switching, but as your code indicates: The library should take care of the disabling/enabling of the devices by itself. No need to touch the SS/CS pins myself.

I will get myself some different SD card today.. and maybe retest in a Windows environment. Any other ides?

I appreciate your help very much and the effort you put in helping me.