[SOLVED] Other problem with dumpfile from SD card

Hi,

I detected other problem with dumpfile example coming with Arduino IDE 22.

I modified a little bit the code to allow to download it when it receives a 'D' letter from the serial port. I also included other option such as to set the time of the arduino,when it receives a 'T'. here is the code:

#include <Time.h>
#include <SD.h>

const int chipSelect = 10;

#define TIME_MSG_LEN  11   // time sync consists of a HEADER followed by ten
                           // ascii digits
#define TIME_HEADER  'T'   // Header tag for serial time sync message

void setup()  {
  pinMode(10, OUTPUT);
  Serial.begin(115200);
  Serial.print("Wellcome to my device");
  delay(1000);
  Serial.print("T");
  Serial.println(now());
  delay(1000);
}

void loop(){
  if(Serial.available() )
  {
    processSyncMessage();
  }
  /*if(timeStatus()!= timeNotSet)
  {
    // here if the time has been set
    digitalClockDisplay();
  }*/
  digitalClockDisplay();
  delay(2000);
}

void digitalClockDisplay(){
  // digital clock display of the time
  Serial.print("1;");
  Serial.print(day());
  Serial.print("-");
  printDigits(month());
  Serial.print("-");
  Serial.print(year());
  Serial.print(";");
  Serial.print(hour());
  Serial.print(":");
  printDigits(minute());
  Serial.print(":");
  printDigits(second());
  Serial.println(";7.74;5.02;23.32;0.00;0.00;0.00;94925;12.12;1;12.37;0;0;0;0;0;0;0");
}

void printDigits(int digits){
  // utility function for digital clock display: prints preceding colon 
  // and leading 0
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

void setuptime(){
  time_t pctime = 0;
  for(int i=0; i < TIME_MSG_LEN -1; i++){
    char c = Serial.read();
    if( c >= '0' && c <= '9'){
      pctime = (10 * pctime) + (c - '0') ; // convert digits to a number
    }
  }
  setTime(pctime);   // Sync clock to the time received on serial port
  Serial.print('T');
  Serial.print(now());
  delay(1000);
  return;
}

  
void DownloadData(){
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    return;
  }
  Serial.println("card initialized.");
  File dataFile = SD.open("datos.log");
  Serial.println(dataFile.size());
  if (dataFile) {
    while (dataFile.available()) {
      Serial.write(dataFile.read());
    }
    dataFile.close();
    Serial.println("Completed");
  }  
  else {
    Serial.println("error opening datos.log");
  } 
  return;
}
void processSyncMessage() {
  if(Serial.available() >=  0 ){  
    char c = Serial.read() ;
    if( c == 'T' ) {
      setuptime();
    }
    if ( c == 'D'){
      DownloadData();
    }
  }
  return;
}

It works perfect, except that i can not do more than one time the dumpfile. I can repeat as many times as i want the time setting. But i cannot repeat the dumpfile. The first time is works (with an small problem, such as i reported here: http://arduino.cc/forum/index.php/topic,70576.0.html), but if i try it again, it returns "Card failed, or not present'...
It only works after a reset...

Any idea about how could i solve this? Thanks!

Why do you do the SD.begin() in DownloadData()? That should be done once in setup(), not every time you want to access the data on the card.

Hi PaulS,

I understand that this sentence is OK, because this first IF inside de DownloadData proceduce try to check if the SD card is already beganing. If yes, it follow to try to open de file. If not, it return, that there is problem with the access to the SD.

The code comes from the example, just a little bit modified, so i am not the author of this sentence in the code, but since it has a "!" symbol, it is not trying to start the SD, just only to check if it is already done. Am i right?

However, it does not mind where i declare SD.begin(chipSelect), the result is that the SD card in not accesible. So it means that SD.Begin must not be declared anywhere (neither the Setup and loop). Otherwise, it does not work. Try it if you want. I tried writing it in different sections of the code (setup, loop, procedures...) without result.

Let me know if you have better results! Thanks a lot PaulS!

The code comes from the example, just a little bit modified, so i am not the author of this sentence in the code, but since it has a "!" symbol, it is not trying to start the SD, just only to check if it is already done. Am i right?

No, I'm sorry, you are not.

The SD.begin() function attempts to initialize the card, and return true if successful, or false, if not.

The ! in front says to negate the logic state returned by the SD.begin() function, for the purposes of the if test.

The code is equivalent to:

boolean openStatus = SD.begin(chipSelect);
if(openStatus == false)
{
    Serial.println("Card failed, or not present");
    return;
}

Written this way, you can see that the SD.begin() function gets called every time DownloadData() gets called, which is not what you want to do, since SD.begin() WILL fail if called a second time, apparently.

I'd move the Sd.begin() call, and related error handling, to setup().

You are right PaulS,

Sorry, i had exactly that on mind, but i see that i explained completely incorrectly (may be because english is not my native languaje). In any case, what you say is very clear. I will try to move the test part to the setup section and see whats happen. I will report here later the results.

Thanks PaulS!

ok, thanks to PaulS, the problem is solved.

The solution is to remain this section of code in the Setup section:

if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
  }

And it must be removed from the DownloaData procedure (in my case, but even out of the loop section). Them everytime i want to dump a file it works!! So, the problem is solved!

Thanks PaulS for your clear explanations and help!