Go Down

Topic: SD.open hanging device? (Read 2265 times) previous topic - next topic

kobowi

I'm a bit of an arduino noob so bear with me... I have an ethernet shield with SD card reader (with my Diecimila). Got it connected to the network fine, but I'm getting problems reading from the SD card. If I use this program:

Code: [Select]
#include <SD.h>

// set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
SdFile root;

// change this to match your SD shield or module;
// Arduino Ethernet shield: pin 4
// Adafruit SD shields and modules: pin 10
// Sparkfun SD shield: pin 8
const int chipSelect = 4;   

void setup()
{
// Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);
  Serial.flush();
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");
  Serial.flush();
  delay(1000);
File f = SD.open("TEST.TXT");
  if(f) {
   while(f.available()) {
     Serial.write(f.read()); 
   }
  } else { Serial.println("No open"); }
}

void loop(void) {
 
}


I get no output whatsoever. If I comment out the SD.open part:

Code: [Select]

  }
  Serial.println("card initialized.");
  Serial.flush();
  delay(1000);
/*File f = SD.open("TEST.TXT");
  if(f) {
   while(f.available()) {
     Serial.write(f.read()); 
   }
  } else { Serial.println("No open"); }*/
}


Then I get output on the serial port. So it seems like SD.open hangs my device. How can I resolve this?

SurferTim

Try this:
Code: [Select]
#include <SD.h>

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

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

 if(!SD.begin(4)) Serial.println("SD fail");
 else Serial.println("SD ok");
}

void loop() {
}

Do you get fail or ok on the serial monitor?

kobowi

Hi SurferTim. With your code I got "SD ok". I then added in the failing section from above to give this:

Code: [Select]

#include <SD.h>

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

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

  if(!SD.begin(4)) Serial.println("SD fail");
  else Serial.println("SD ok");
 
  File f = SD.open("TEST.TXT");
  if(f) {
   while(f.available()) {
     Serial.write(f.read()); 
   }
  } else { Serial.println("No open"); }
}

void loop() {
}


The output from the serial monitor is then "SD T". So I'm convinced there is a buffer overflow somewhere, but it's a bit of a mystery to me. If I add "Serial.println("Open OK");" right after "if(f) {" then I get a bunch of random characters. After a couple of resets it then started spitting out "SD" multiple times.

Just to try and rule out it being a bad board/shield, the analog web server example works absolutely fine.

SurferTim

What is in the file TEST.TXT?

kobowi

It just contains

Code: [Select]

Hello, world!\n


(i.e. it ends with a new line).

SurferTim

I know this sounds strange, but you may be running out of memory. Not program memory, but SRAM. The diecimila has only 1K SRAM. From my understanding, the SD functions use a 512 byte SRAM buffer and other SRAM memory too.

kobowi

No, that sounds perfectly reasonable. I've managed to hit the limit before doing things over the Serial port with the LCD library and some other external hardware (I'm far to used to these fancy x86 devices with their comparatively near infinite RAM :-)

So I've probably got two options then:

1. I guess the FAT parts of the library are going to be the most resource intensive - so would it be a better idea to access the SD 'raw' (would this work kind of like writing to an external EEPROM?). I found some code to do this (http://arduino.cc/playground/Code/SDCARD) - it seems pretty involved but might work well as a bit of a hack.

2. A board with more memory - perhaps one of the mega ones? (FWIW I'm up to about 13k of 14k available bytes in the program memory so this might be a better long term choice)

Any thoughts?

SurferTim

I use a Mega2560. It has 8k of SRAM. I do not open multiple SD files simultaneously, but fat16lib says you can. It takes 512 bytes (or more) SRAM for each file opened.

kobowi

Cool. Well I might try and hack around it for now, but I'll have a look around for a 2560 or something similar.

Thanks for all your help, SurferTim :)

fat16lib

Remove this stuff:
Code: [Select]

// set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
SdFile root;


It duplicates stuff already in SD.h.

Marc Porlier

Hi TIM,

I am scratching my head here. I simply can not get my SD card to be detected with this simple sketch! I have a Leonardo+Ethernet/SD shield and nothing else. I use a 5V external PWS and obviously keep my USB connected. I have tryed the latest SdFat.h library and communication works fine so I know its not the card or the PINs...  :smiley-roll-sweat: If you have any pointers. I would have suspected the exemples would have worked by know but it looks like not.

Marc


Try this:
Code: [Select]
#include <SD.h>

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

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

 if(!SD.begin(4)) Serial.println("SD fail");
 else Serial.println("SD ok");
}

void loop() {
}

Do you get fail or ok on the serial monitor?

Marc

el_supremo

You are rather close to the edge with a Diecimila. The first sketch you posted has this ram usage:
Code: [Select]
text=13190 data=140 bss=845
flash =  13330   (text+data)
sram  =    985   (data+bss)


Which means (if I used the same libraries that you did) there's only 39 bytes free for the stack and local variables. Probably not enough.

Pete

Go Up