Go Down

Topic: [SOLVED] Is it possible to use Eth and SD card on the Arduino Ethernet (Read 941 times) previous topic - next topic

Depicus

I have the Arduino Ethernet (http://arduino.cc/en/Main/ArduinoBoardEthernet) and am having brain death on getting the ethernet and sd card to work at the same time. On their own they both work but as soon as I add the SD.h file things go wrong and I have to power off the Arduino before I can get anything working again. Anybody have any working code or an idea what I am doing wrong ?

This is my basic stripped down code.

Code: [Select]

#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <Time.h>  
//#include <MemoryFree.h>
#include <SD.h>

byte mac[] = {
 0x90, 0xA2, 0xDA, 0x00, 0xF2, 0x1E };    
EthernetClient client;
EthernetUDP Udp;
byte SNTP_server_IP[]    = { 192, 43, 244, 18}; // time.nist.gov
const long timeZoneOffset = 0L; // set this to the offset in seconds to your local time;

/* sd card */
Sd2Card card;
SdVolume volume;
SdFile root;
const int chipSelect = 4;

void setup() {    
 Serial.begin(9600);
 //pinMode(10, OUTPUT);

 Serial.println("Starting...");  
 pinMode(6, OUTPUT);
 digitalWrite(6, HIGH);

 /* Check SD Card */

 Serial.println("Initializing SD card...");
 //digitalWrite(10, HIGH); // If it's low, the Wiznet chip corrupts the SPI bus

 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?");
 }
 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");
   }
 }



 /* Get DHCP Address */
 //digitalWrite(10, HIGH);
 Serial.println("Requesting DHCP Address.");
 if (Ethernet.begin(mac) == 0) {
   Serial.println("Failed to configure Ethernet using DHCP");
   // no point in carrying on, so do nothing forevermore:
   for(;;)
     ;
 }

 // print your local IP address:
 Serial.print("IP Address assigned: ");
 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();
 Udp.begin(4343);
 delay(500);
 Serial.println("Waiting for NTP time sync");
 setSyncProvider(getNtpTime);
 while(timeStatus() == timeNotSet)  
   ; // wait until the time is set


 //connectToServer();
 //digitalWrite(10, LOW);
}


SurferTim

I use them both in the same sketch. I use this setup stuff.
Code: [Select]
// put your includes and network variables here
void setup() {
  Serial.begin(9600);

  // disable w5100 while setting up SD
  pinMode(10,OUTPUT);
  digitalWrite(10,HIGH);

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

  Ethernet.begin(mac,ip);
  // Ethernet.begin() returns with its SPI enabled, so you must disable it.
  digitalWrite(10,HIGH);

  Serial.println("Ready");
}

void loop() {


I would not add any more code until you get "SD ok" and "Ready".

PaulS

Quote
On their own they both work but as soon as I add the SD.h file things go wrong and I have to power off the Arduino before I can get anything working again.

That would indicate that the problem is not hardware related.

Quote
Anybody have any working code or an idea what I am doing wrong ?

The SD library writes to the SD card in 512 byte chunks, regardless of how much data you want to write to the file. Therefore it needs a 512 byte buffer. That's 1/4 of the available memory.

Code: [Select]
    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?");
    Serial.println("Wiring is correct and a card is present.");
    Serial.print("\nCard type: ");
      Serial.println("SD1");
      Serial.println("SD2");
      Serial.println("SDHC");
      Serial.println("Unknown");
    Serial.println("Failed to configure Ethernet using DHCP");
  Serial.println("Waiting for NTP time sync");

None of these strings NEEDS to be be in SRAM, yet they all are, and they are using up what little memory you have available.

It's time for you to learn about PROGMEM. (1.0 makes using program memory for strings like this very easy:
    Serial.println(F("Wiring is correct and a card is present."));
is all that is needed.


Depicus



It's time for you to learn about PROGMEM. (1.0 makes using program memory for strings like this very easy:
    Serial.println(F("Wiring is correct and a card is present."));
is all that is needed.



Will do, was only born into the Arduino world on Friday so still learning but thank you both for the replies, will try both suggestions.

SurferTim

If you want to look at a sketch that handles both the w5100 and the microSD, here is a passive FTP client sketch. Maybe it will give you some ideas.
http://arduino.cc/forum/index.php/topic,93502.msg707104.html#msg707104

Depicus

Thank you both, all working now.

Here is what I did.

Code: [Select]

  /* Check SD Card */
  Serial.println(F("Initializing SD card..."));
  pinMode(10,OUTPUT); // disable w5100 while setting up SD
  digitalWrite(10,HIGH);

  if (!card.init(SPI_HALF_SPEED, chipSelect))
  {
    Serial.println(F("initialization failed. Things to check:"));
  }
  else
  {
    Serial.println(F("Wiring is correct and a card is present."));
    // print the type of card
    Serial.print(F("\nCard type: "));
    switch(card.type()) {
    case SD_CARD_TYPE_SD1:
      Serial.println(F("SD1"));
      break;
    case SD_CARD_TYPE_SD2:
      Serial.println(F("SD2"));
      break;
    case SD_CARD_TYPE_SDHC:
      Serial.println(F("SDHC"));
      break;
    default:
      Serial.println(F("Unknown"));
    }
  }

  /* Get DHCP Address */
  Serial.println(F("Requesting DHCP Address."));
  if (Ethernet.begin(mac) == 0) {
    Serial.println(F("Failed to configure Ethernet using DHCP"));
    // no point in carrying on, so do nothing forevermore:
    for(;;)
      ;
  }
  else
  {
    // Ethernet.begin() returns with its SPI enabled, so you must disable it.
    digitalWrite(10,HIGH);
  }

SurferTim

Is there a reason you are not using the Arduino SD library?
http://arduino.cc/en/Reference/SD

Depicus


Is there a reason you are not using the Arduino SD library?
http://arduino.cc/en/Reference/SD



It was using the code from the CardInfo example sketch so presumed it was the SD stuff.

SurferTim

This does all you are doing with the card.init stuff, and it sets the SS pin correctly.

Code: [Select]
if(SD.begin(4) == 0) Serial.println("SD fail");
else Serial.println("SD ok");


Now you can use all those SD functions in the SD library.


Go Up