Ethernet Shield + SD Card

I would like to have my ethernet to initialize before my SD initilization. May I know if this is possible? I couldn't get the following code to run, can you please help to advise on my code?

The scenario below: connection to google is successful but the SD cannot get initialized. (May I know why the SD cannot be used whenever it's after ethernet.begin?

Please advise. Thanks

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

// this must be unique
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };  

// change to your network settings
IPAddress ip( 192, 168, 1, 106 );    
IPAddress gateway( 192, 168, 1, 1 );
IPAddress subnet( 255, 255, 255, 0 );

EthernetServer server(8080);

EthernetClient client;

File myFile;

void setup()
{
  Serial.begin(9600);
 
  pinMode(10, OUTPUT);      // set the SS pin as an output (necessary!)
  
  
    digitalWrite(10, LOW);   
    digitalWrite(4, HIGH);
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  
  Serial.println(Ethernet.localIP());
  
    if (client.connect("www.google.com", 80)) {
    Serial.println("connected");
    }
    else
    {
    Serial.println("connection failed");
    }
    
   client.stop();
    
    if(!client.available()) 
    {
    Serial.println("client disconnected");
    }
    else
    {
    Serial.println("client is still ACTIVE");
    }
    
    
  
  pinMode(10, OUTPUT);      // set the SS pin as an output (necessary!)
    digitalWrite(10, HIGH);   // but turn off the W5100 chip!


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

  if (!SD.begin(4)) {
    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
}

Try this in your setup function.

void setup() {
  Serial.begin(9600);
 
  // disable all device SPI
  pinMode(10, OUTPUT);      // set the SS pin as an output (necessary!)
  digitalWrite(10, HIGH);   
  pinMode(4,OUTPUT);
  digitalWrite(4, HIGH);

  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  
  Serial.println(Ethernet.localIP());
  
    if (client.connect("www.google.com", 80)) {
    Serial.println("connected");
    }
    else
    {
    Serial.println("connection failed");
    }
    
   client.stop();
    
    if(!client.available()) 
    {
    Serial.println("client disconnected");
    }
    else
    {
    Serial.println("client is still ACTIVE");
    }
  
  Serial.print("Initializing SD card...");

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

  // rest of your setup code

Surfertim,

thanks for your reply. I tried your recommendation but it's still not working. What is your other thought?

ethernet.JPG

OK. Try this sketch. It disables the w5100 SPI immediately and starts the SD. Does this work?

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

void setup()
{
  Serial.begin(9600);
 
  pinMode(10, OUTPUT);      // set the SS pin as an output (necessary!)
  digitalWrite(10, HIGH);   // but turn off the W5100 chip!

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

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

void loop() {
}

Sufertim,

Yes, it did. Any idea why didn't work if I change the sequence?

OK. Just wanted to check if your SD card was working. Now it is just a matter of troubleshooting it.

Try this code. Maybe the ethernet library is leaving D10 LOW after the startup.

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

// this must be unique
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };  

// change to your network settings
IPAddress ip( 192, 168, 1, 106 );    
IPAddress gateway( 192, 168, 1, 1 );
IPAddress subnet( 255, 255, 255, 0 );

void setup() {
  Serial.begin(9600);
 
  // disable all device SPI
  pinMode(10, OUTPUT);      // set the SS pin as an output (necessary!)
  digitalWrite(10, HIGH);   
  pinMode(4,OUTPUT);
  digitalWrite(4, HIGH);

  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  
  Serial.println(Ethernet.localIP());
  
  // insure w5100 SS is HIGH before starting SD
  digitalWrite(10, HIGH);

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

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

void loop() {
}

surfertim,

Tried, not working.... it's weird, isn't it? Please see the output below. Any thought what else could be the issue?

ethernet3.JPG

I ran that exact code above.

192.168.1.106
Initializing SD card...initialization done.

What Arduino and shield are you using?

surfertim,

I use Mega and ethernet shield. Do you suspect it's the wiring or library which I used? Do you mind to send me your library for SD and Ethernet?

I'm using IDE v1.0.5, the standard ethernet library, and a R2 Mega 2560 with the R2 ethernet shield. Neither have the two extra pins like the R3 models.

edit: I use the standard SD library also. What do you mean by "wiring"? You should be able to plug it into the Mega.
add: unless the shield is a R3 and the Mega is a R2. If there are two pins overlapping on each side, then you need to jumper one pin (5V to IOREF).

surfertim,

I think I screwed up with the library. I tried your script with a newly installed IDE (in another directory) and it worked! I didn't know what was altered to the library.

Just need another advice from you. How can I use SD and ethernet together if I plan to upload a file to FTP server? Do I need some sort of INTERRUPT to have both devices (ethernet and SD) to work together? Thanks

They work well together. I use them together for both web server and FTP passive client sketches.
http://playground.arduino.cc/Code/WebServerST
http://playground.arduino.cc/Code/FTP

SurferTim,

Thanks for the code! It would be very useful.

I have a thought of a project... I need your advice:

I would like to log the temp of surrounding. The data will be save and uploaded to the FTP server after 5 mins (the temp will still be logged into a new file while the ethernet upload the previous file to FTP server). Do you think I can accomplish this project with single SD card or I need two SD cards (one for uploading whereas another one for logging)? Can I do simultaneous tasks (loging while uploading) with arduino? Thanks!

This is an Arduino. There is no "simultaneous". You should be able to save the data on the SD, then upload it to the server between (usually immediately after) file updates.
Open the file for write.
Save the data.
Close the file.
If time for an upload to the FTP server:
Reopen the file for read.
Send the file.
Close the file.

Ok...I was thinking if I could perform datalogging and uploading simultaneously.

Another issue:

when I tried to connect to a FTP server, I got the following output error. I wonder why it couldn't establish data connection? When I tried to connect to this server using Filezilla, there was no issue. Can you help? Thanks

initialization done.
Press f or r
SD opened
Command connected
220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
220-You are user number 4 of 50 allowed.
220-Local time is now 23:44. Server port: 21.
220-This is a private system - No anonymous login
220-IPv6 connections are also welcome on this server.
220 You will be disconnected after 15 minutes of inactivity.
331 User prototec OK. Password required
230 OK. Current restricted directory is /
215 UNIX Type: L8
257 "/" is your current location
200 TYPE is now 8-bit binary
227 Entering Passive Mode (103,9,101,121,182,139)
Data port: 46731
Data connection failed
FTP FAIL

It looks like you are doing great until you try to open another connection. Are you out of sockets? Add this function to your sketch, then call it just before starting your FTP code. You need at least 2 sockets available (status 0X0). One for the command channel, and one for the data channel.

#include <utility/w5100.h>

byte socketStat[MAX_SOCK_NUM];

void ShowSockStatus()
{
  for (int i = 0; i < MAX_SOCK_NUM; i++) {
    Serial.print(F("Socket#"));
    Serial.print(i);
    uint8_t s = W5100.readSnSR(i);
    socketStat[i] = s;
    Serial.print(F(":0x"));
    Serial.print(s,16);
    Serial.print(F(" "));
    Serial.print(W5100.readSnPORT(i));
    Serial.print(F(" D:"));
    uint8_t dip[4];
    W5100.readSnDIPR(i, dip);
    for (int j=0; j<4; j++) {
      Serial.print(dip[j],10);
      if (j<3) Serial.print(".");
    }
    Serial.print(F("("));
    Serial.print(W5100.readSnDPORT(i));
    Serial.println(F(")"));
  }
}

A socket status list:
0X0 = available.
0x14 = socket waiting for a connection
0x17 = socket connected to a server.

Surfertim,

I think you are right that I don't have the socket. Please see the status below. Can you advise how do I overcome this problem? thanks

initialization done.
Press f or r
Socket#0:0x0 0 D:0.0.0.0(0)
Socket#1:0x0 0 D:0.0.0.0(0)
Socket#2:0x0 0 D:0.0.0.0(0)
Socket#3:0x0 0 D:0.0.0.0(0)
SD opened
Command connected
220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
220-You are user number 2 of 50 allowed.
220-Local time is now 10:22. Server port: 21.
220-This is a private system - No anonymous login
220-IPv6 connections are also welcome on this server.
220 You will be disconnected after 15 minutes of inactivity.
331 User prototec OK. Password required
230 OK. Current restricted directory is /
215 UNIX Type: L8
257 "/" is your current location
200 TYPE is now 8-bit binary
227 Entering Passive Mode (103,9,101,121,153,82)
Data port: 39250
Data connection failed
FTP FAIL

You have all sockets available. That is fine.

Have you tried FTP with that server with other FTP software? Maybe you have a firewall issue. FTP uses two ports. Port 21 is the command port and if using passive FTP, the server sends another port for the data channel. It is possible the server is blocking the data port. This is the data port it sent your Arduino in the last result you posted, but that changes with every connection as you can see in comparison to your first result.

Data port: 39250
Data connection failed

Okay...I thought I didn't have the socket.

I can FTP to this server without any issue using Filezilla. However, I had the issue when I used telnet. However, the administrator claimed that it's the issue with my local firewall. What is your thought?

If I can't use passive mode, I can use active mode for uploading? Can you adivse? Thanks

FTP active mode is more difficult on the Arduino end, and doesn't go through router firewalls without port forwarding. Your best bet is stay with passive mode.

The way this works with active mode is the client connects to the server on the command port, then the client tells the server which port it is listening on. Then the server attempts to connect to that port on the client as a client and the client becomes a "server". That is where the router firewall will block that connection.

With passive mode, the client is a client on both ports, eliminating the need for any modifications to the router nat or firewall to allow the FTP server to connect to the client.

BTW: If the FTP server didn't like passive mode, it would not have sent the Arduino this:

227 Entering Passive Mode (103,9,101,121,153,82)