Arduino Mega + W5100 w/MicroSD ... cant even get it started!

Hello Folks,

after literally hours of trying various methods of getting my W5100 board to connect to my Mega I've conceded defeat and Im asking for help.

for my project im building essentially a datalogging device, Although I've made various LED/LCD/probe projects I've yet to use any internet based communication.

Im now trying to work on both sides of this project (mass storage and Ethernet connection) but Im getting nowhere.

I've tried manually remapping the pins of the w5100 to the mega as recommended here:

http://mcukits.com/2009/04/06/arduino-ethernet-shield-mega-hack/

but that didnt work, other documentation online says that with the newer boards there is actually no need to hack the hardware or SPI software,

(my board says MEGA Compatible).

So my first question is I cant tell If A) I need to change any hardware or software or if i can just stack it as a shield and run the code.

I tried without remapping the pins tried writing the Mac address and my network IP address but I got a connection fail im at a friends house this weekend but im using port 80/81 which are usually default open if I remember correctly.

On my W5100 board the sticker says "HanRun" HR911105A 11/16 (however a quick google says thats just the RJ45 jack part number etc) and was purchased from :

http://www.ebay.co.uk/itm/Ethernet-Shield-05-W5100-For-Arduino-UNO-MEGA-1280-2560-/130646984479?pt=LH_DefaultDomain_0&hash=item1e6b2ac71f

Secondly for the SD memory card side (I know its the wrong subforum) however Im using a 4gb MicroSDHC card, I've yet to find any schematics to say I cant use a card larger than Xmb/gb or it must be an older microSD not a SDHC card.

if anyone could shed any light on this I would be eternally grateful.

Luke

No pin bending required if the shield has a 6 pin ICSP connector.

void setup()
{
   Serial.begin(9600);

   // just to be safe, I disable the w5100 SPI while starting the SD SPI
   // I had problems in restarting without this in my FTP code
   pinMode(10,OUTPUT);
   digitalWrite(10,HIGH);

   // start the SD card
   // this begin returns with the SD SPI disabled
   if(SD.begin(4) == 0)  Serial.println("SD fail");

   // start the ethernet port
   // this begin returns with the w5100 SPI enabled
   Ethernet.begin(mac,ip);
   // so disable the w5100 SPI
   digitalWrite(10,HIGH);

   // rest of your setup
}

Now you should be able to read and write to both without managing the Slave Select lines. That is performed by the low level read and write routines in the libraries.

Thank you SurferTim for the response.

Yes my unit has a 6 pin ICSP so that answers the first question so thank you.

I've had a look at your code which you supplied unless i've missed something obvious Im still getting an error (infact its stopping at the SD card check not the Ethernet check).

Heres the code I tried:

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

const int chipSelect = 4;
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,1, 254 };

void setup()
{
  Serial.begin(9600);
   // just to be safe, I disable the w5100 SPI while starting the SD SPI
   // I had problems in restarting without this in my FTP code
   pinMode(53,OUTPUT); //location of the SS pin, 53 on the Mega, 10 on other
   digitalWrite(53,HIGH);
}

void loop()
{
   // start the SD card
   // this begin returns with the SD SPI disabled
   if(SD.begin(chipSelect) == 0)  Serial.println("SD fail");

// start the ethernet port
   // this begin returns with the w5100 SPI enabled
   Ethernet.begin(mac,ip);
   digitalWrite(10,HIGH);

}

The microSD card is a 4Gb SDHC card which is known to work so its not the card however it keeps bouncing back as a fail.

Ive also tried:

#include <SD.h>

File myFile;

void setup()
{
  Serial.begin(9600);
  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(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
}

That also failed.. I've tried it with my other MicroSD card which is an 8GB SDHC card.

Hmm (I know this is slighly siding away from Networking, however it uses the W5100 shield and I have plenty of questions to do with network communications as well!)

Any Ideas folks?

Best regards
Luke

I recommend trying just this until you get the SD card to work (SD ok):

#include <SD.h>

void setup()
{
   Serial.begin(9600);

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

   if(SD.begin(4) == 0)
   {
      Serial.println("SD fail");
   }
   else
   {
      Serial.println("SD ok");
   }
}

void loop()
{
}

It will fail if the microSD format is incorrect. I hear others have problems with microSD cards larger than 2GB. Mine is 2GB and works well with the format it came with.

Ah thats interesting,
I couldnt find any documentation regarding maxium memory size but that could possibly fit, I've only used a 4Gb and an 8 GB card as its the only cards ive got to hand however I shall place an order for a smaller card.

edit: I've found a working 2 Gb microSD card but this has also failed when I tried your code below.

Shield busted? IDE(im using Arduino 0022)/arduino Core files playing up?

either way I might try and work in the network connection but I do need to sort this SD card problem out.

Below is another discussion that may apply to your situation.

http://arduino.cc/forum/index.php/topic,100176.0.html

Thank you ZoomKat,

Ive read through that thread, its not the coding that the issue persay, in that it definately uploads, and it definately runs correctly it just cant "see" the SD card,

I've tried:

a new clean IDE
known working cards (4/8 Gb MicroSDHC cards, a 2 Gb MicroSD)

Unfortunately Im going to struggle getting a replacement shield if its busted as I have a tight deadline for my project (needs to be done in 1 month time due to commitments). So I hope it isnt the shield =/

Anyone think of anything obvious that i might have missed?

I currently have my arduino stacked directly to the Ethernet shield v5.0/W5100

Luke

Huzzah!

Finally managed to get somewhere with the shield!

the problem lay in where and how I was allocating the Wiznet5100 chip and the SD,

because the W5100 and SD card share the SPI bus, only one can be active at a time.I needed to explicitly deselect it. To do this with the SD card, I set pin 4 as an output. For the W5100, I then set digital pin 10 as a high output

using the default SD example

#include <SD.h>

File myFile;

void setup()
{
  Serial.begin(9600);
  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(10, OUTPUT);//sets w5100chip 
  digitalWrite(10,HIGH); // disables w5100 
  pinMode(4, OUTPUT); // sets SD chip
  //digitalWrite(4,HIGH);//disables SD chip

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

  if (SD.exists("example.txt")) {
    Serial.println("example.txt exists.");
  }
  else {
    Serial.println("example.txt doesn't exist.");
  }

  // open a new file and immediately close it:
  Serial.println("Creating example.txt...");
  myFile = SD.open("example.txt", FILE_WRITE);
  myFile.close();

  // Check to see if the file exists: 
  if (SD.exists("example.txt")) {
    Serial.println("example.txt exists.");
  }
  else {
    Serial.println("example.txt doesn't exist.");  
  }

  // delete the file:
  Serial.println("Removing example.txt...");
  SD.remove("example.txt");

  if (SD.exists("example.txt")){ 
    Serial.println("example.txt exists.");
  }
  else {
    Serial.println("example.txt doesn't exist.");  
  }
}

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

Least thats a step in the right direction,

Im just going to work on the networking side of it, Ultimately Id like to use it to send an email (via telnet im assuming) (and it worked with the 4GB SDHC card)

Luke ^^

Good to hear it is working for you now.

There are posts with SMTP code examples around. I have one somewhere on the forum for v0022, and zoomkat translated it to v1.0.

edit: When you start with the ethernet shield, insure you follow the setup() code in reply #1. That sets all the SS pins correctly so the low level code in the libraries can handle them. The w5100 SPI must be disabled again after the Ethernet.begin() call.

I shall definately have a look at it next,

out of interest if there any threads that you know of which would be useful for SMTP or similar by all means post a link etc.

Now that Ive got the SD card side of the program working im just intergrating that in and shall have look at the "networking" side of it once I've got the SD card linked.

Luke

Here is a thread with my code modified to v1.0 by zoomkat.
http://arduino.cc/forum/index.php/topic,84049.0.html

Bear in mind that code has the bad Ethernet.begin() format. That is the way it is in the reference page, but it is incorrect. It does not mention the dns server ip required after the ip. You need to use this:

Ethernet.begin(mac,ip,dns,gateway,subnet);

If you do not plan on using dns, you can use the gateway for the dns server.

Ethernet.begin(mac,ip,gateway,gateway,subnet);

Some new email test code that worked with my ISP's smtp server:

//zoomkat 4/08/12
//email test code using DNS
//developed from code posted by various persons

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

#include <SPI.h>
#include <Ethernet.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
char serverName[] = "smtp.yourISP.net"; // your ISP's SMTP server
EthernetClient client;

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

void setup(){
  Serial.begin(9600); 
  Serial.println("DNS and DHCP-based email test 4/08/12"); // so I can keep track of what is loaded
  Serial.println("Send an e in serial monitor to test"); // what to do to test
  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    while(true);
  }
  // print your local IP address:
  Serial.print("Arduino IP address: ");
  for (byte thisByte = 0; thisByte < 4; thisByte++) {
    // print the value of each byte of the IP address:
    Serial.print(Ethernet.localIP()[thisByte], DEC);
    Serial.print("."); 
  }
  Serial.println();
  Serial.println();
}

void loop()
{
  byte inChar;
  inChar = Serial.read();
  if(inChar == 'e')
  {
    if(sendEmail()) Serial.println("Email sent"); //start sendEmail()
    else Serial.println("Email failed");
  }
}

//////////////////////////////// email function
byte sendEmail()  //sendEmail() function that returns 1 or 0
{
  //start and check for email server connection
  if (client.connect(serverName, 25)) { 
    Serial.println("connected");
  } 
  else {
    Serial.println("connection failed");
    return 0; //send 0 (failed) back to sendEmail() function
  }
  
  //wait for server "queing" response
  while(!client.available()) delay(1);

  client.println("HELO itismeletschat"); /*hello (statement after helo is needed but irrelevant)*/

  //wait for server "hello" response
  while(!client.available()) delay(1);

  client.println("MAIL From: me@athome.net"); // identify sender, this should be the same as the smtp server you are using*/

  //wait for server "sender ok" response
  while(!client.available()) delay(1);

  client.println("RCPT To: you@athome.net"); /* identify recipient */

  //wait for server "receipent ok" response
  while(!client.available()) delay(1);

  client.println("DATA"); 

  //wait for server to say "enter your message" response
  while(!client.available()) delay(1);
 
  //send email message to server
  client.println("To: you@athome.net"); /* identify recipient */
  client.println("Subject: You Have Arduino Mail!!"); /* insert subject */
  client.println("Please let me know it worked!!!"); /* insert body */
  client.println("."); /* end email */

  //wait for server "message accepted" response
  while(!client.available()) delay(1);

  client.println("QUIT"); /* terminate connection */
  
  //wait for server "goodby" response
  while(!client.available()) delay(1);

  //stop client connection
  client.stop();
  Serial.println("disconnected");
  return 1; //send 1 (success) back to sendEmail() function
}

I know it's been a while since the last reply, but I could not get it working with the standard SD library and my MEGA. I managed to fix this by using the SDFat library instead of the standard SD library which ships with the Arduino IDE.

/*
 * Web Server
 *
 * A simple web server that shows the value of the analog input pins.
 */

#include <SdFat.h>
#include <SdFatUtil.h>
#include <Ethernet.h>
#include <SPI.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 1, 177 };
char rootFileName[] = "index.htm"; 
EthernetServer server(80);

/************ SDCARD STUFF ************/
Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;

boolean listFiles = false;

// store error strings in flash to save RAM
#define error(s) error_P(PSTR(s))

void error_P(const char* str) {
  PgmPrint("error: ");
  SerialPrintln_P(str);
  if (card.errorCode()) {
    PgmPrint("SD error: ");
    Serial.print(card.errorCode(), HEX);
    Serial.print(',');
    Serial.println(card.errorData(), HEX);
  }
  while(1);
}

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!

  setupSD();
  setupNetwork();
}

void setupSD(){
  if (!card.init(SPI_FULL_SPEED, 4)) error("Failed to initalize SD!");
  
  // initialize a FAT volume
  if (!volume.init(&card)) error("Failed to initialize FAT32 volume!"); 
  
  //Test opening root
  if (!root.openRoot(&volume)) error("Testing of SD root failed!");
  
  Serial.print("SD card FAT type: ");
  Serial.println(volume.fatType(),DEC);
  
  Serial.print("Free clusters on card: ");
  Serial.print(volume.freeClusterCount());
  Serial.print(" / ");
  Serial.print(volume.clusterCount());
  Serial.print(" (");
  Serial.print(volume.blocksPerCluster());
  Serial.print(" blocks per cluster)");
  Serial.println();
  
  float totalfreespace = volume.freeClusterCount()*volume.blocksPerCluster();
  totalfreespace = totalfreespace/1000000;
  totalfreespace = totalfreespace*512;
  float totalspace = volume.clusterCount()*volume.blocksPerCluster();
  totalspace = totalspace/1000000;
  totalspace = totalspace*512;
  Serial.print("Free space on card: ");
  Serial.print(totalfreespace);
  Serial.print(" / ");
  Serial.print(totalspace);
  Serial.print(" MB");
  Serial.println();
  
  if(listFiles){
     // list file in root with date and size
    PgmPrintln("Files found in root:");
    root.ls(LS_DATE | LS_SIZE);
    Serial.println();
    
    // Recursive list of all directories
    PgmPrintln("Files found in all dirs:");
    root.ls(LS_R);
    
    Serial.println();
    PgmPrintln("Done");
  }
}

void setupNetwork(){
  Serial.print("Waiting for DHCP to allocate IP address: ");
  Ethernet.begin(mac);
  server.begin();
  
  Serial.println(Ethernet.localIP());  
  
  Serial.println("Network is now ready!");
}

// How big our line buffer should be. 100 is plenty!
#define BUFSIZ 100

void loop()
{
  processWebClient();
}

void processWebClient(){
  char clientline[BUFSIZ];
  char *filename;
  int index = 0;
  int image = 0;
  
  EthernetClient client = server.available();
  if (client) {
    // an http request ends with a blank line
    boolean current_line_is_blank = true;
    
    // reset the input buffer
    index = 0;
    
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        
        // If it isn't a new line, add the character to the buffer
        if (c != '\n' && c != '\r') {
          clientline[index] = c;
          index++;
          // are we too big for the buffer? start tossing out data
          if (index >= BUFSIZ) 
            index = BUFSIZ -1;
          
          // continue to read more data!
          continue;
        }
        
        // got a \n or \r new line, which means the string is done
        clientline[index] = 0;
        filename = 0;
        
        // Print it out for debugging
        Serial.println(clientline);
        
        // Look for substring such as a request to get the root file
        if (strstr(clientline, "GET / ") != 0) {
          filename = rootFileName;
        }
        if (strstr(clientline, "GET /") != 0) {
          // this time no space after the /, so a sub-file
          
          if (!filename) filename = clientline + 5; // look after the "GET /" (5 chars)
          // a little trick, look for the " HTTP/1.1" string and 
          // turn the first character of the substring into a 0 to clear it out.
          (strstr(clientline, " HTTP"))[0] = 0;
          
          // print the file we want
          Serial.println(filename);

          if (! file.open(&root, filename, O_READ)) {
            client.println("HTTP/1.1 404 Not Found");
            client.println("Content-Type: text/html");
            client.println();
            client.println("<h2>File Not Found!</h2>");
            break;
          }
          
          Serial.println("Opened!");
          
          client.println("HTTP/1.1 200 OK");
          if (strstr(filename, ".htm") != 0)
             client.println("Content-Type: text/html");
          else if (strstr(filename, ".jpg") != 0)
             client.println("Content-Type: image/jpeg");
         else if (strstr(filename, ".gif") != 0)
             client.println("Content-Type: image/gif");
         else 
             client.println("Content-Type: text");

          client.println();
                
          String line = "";
          char character;
          int i = -1;
          
          long startTime = millis();
          float average = 0;
          while ((character = file.read()) >= 0) {
              client.print(character);
          }
          
        } else {
          // everything else is a 404
          client.println("HTTP/1.1 404 Not Found");
          client.println("Content-Type: text/html");
          client.println();
          client.println("<h2>File Not Found!</h2>");
        }
        break;
      }
    }
    // give the web browser time to receive the data
    delay(1);
    client.stop();
  } 
}

FYI: My Mega 2560 and ethernet shield works fine with the standard SD library.

It does yes, but not at the same time, even using the offcial examples.

It does at the same time using my example. Here is my web server code that serves files from the SD card using the standard SD library:
http://playground.arduino.cc/Code/WebServerST

Thanks for the details, I uploaded your code with adjustments for the network settings~~, but it fails when initalizing the SD card. The response is: "Starting SD..failed". I also tried 53 for chipselect but same result.~~. and it works now, using standard SD library!

I don't mind using the SDFat library as it seems to provide more functions and performs a little bit better. I just wanted to share the code which worked for me, because it took me several hours to get it working. It might save some time for someone else who is experiencing the same problem.