SD Card Optional

03 Sep 2010

If a SD card is plugged into the socket, I want to read a file from it, else I want to do something else

I thought that the 'if (fd)' in the following code would handle this, but if the card is not inserted it just sits there generating error messages. any ideas on how to fix this?

Minor Complaint: The terminal in Flash Magic (and some others) does not allow allow conversion of<LF> to <CR><LF> so the error messages form one continuous line that is very hard to read. Can someone find a few '\r' to add to the file system error messages?

if (!FileOpen)  // Only read file once
       {
          FILE *fp = fopen("/sd/besc1.txt", "r");
          if(fp) 
          {
             printf("Script File Open\r\n");
             FileOpen = TRUE;
             Fptr = 0;
             while (fgets(block, 128, fp))
             {
//              printf("%s",block);
                strcpy(BlockFile[Fptr++],block);
             } 
             FptrMax = Fptr - 1;
             printf("Script File Read\r\n");
             fclose(fp); 
          }    
       } 

05 Sep 2010

Hello John,

You could add an carddetect, all SdCard Connector have one.

Localize the "carddetect" pin on your Sdcard connector, connect it into a Mbed I/O (p15 why not ?) with a pullup resistor (10k Ohm).

Like this :

SdCard_Mbed

(warning : the package is from Spakfun, with a little issue WP = CD (CardDetect) and CD = WP on the real Spakfun SdCard connector (PRT-00136)).

In my project (datalogger), mbed did not start until an sdcard is present :

......

DigitalIn cardDetect(p15);    //for example

......

//wait an Sdcard...
while (cardDetect)
{
debugNewLine("No Sdcard detected");
statusLed = !statusLed;
}

//----- Mount filesystem with "sd" handler on my SdCard
SDFileSystem sd(p5, p6,p7,p8, "sd");  // do(MOSI),di(MISO),clk,cs

........

For the moment i did not "catch" error from "FatFileSystem", i'm a mBed rookie, i will work on it ASAP ! ;-)

Hope this help.

Chris

 

07 Sep 2010

Using Card Detect is a good idea, but I also have to cover the situation where the wrong SD card has been inserted. I think it should be possible for the code to recover by using something like

         FILE *fp = fopen("/sd/besc1.txt", "r");
          if(!fp) 
          {
               fclose(fp);
               printf("File not found\r\n"); 
          }
          else
          {
               .......
          }    

if the file is not on the SD card or if the card is not installed. However I cannot get anything like this to work. It seems to never get to the if(!fp) and hangs sending error messages.

07 Sep 2010

If fp is 0, you don't need to close it (since the opening failed). Maybe that's where your program crashes?

07 Sep 2010

I commented out the fclose(fp); but still got a message:

No disk, or could not put SD card in to SPI idle state

The "File not found" message did not show, and the code was hung.

I think the message "No disk, or could not put SD card in to SPI idle state" is tied to stderr, perhaps there is no provision for recovery from a stderr event?

09 Sep 2010

(please excuse the slightly off-topic question but it seems that John may have solved some problems that I have been stuck on for a while now and I'd love to know how you did it. I have read a lot of the other SD card threads which have been really helpful up to this point but now that I am here they are all seeming quite dead )

Are you able to successfully use SD cards that are newer than version 1.0? (ie. not limited to the very few cards purported to work on the cookbook page).

If so, which ones and how did you do it?

The SD card spec shows that there are other branches of the initialisation tree to be covered beside the ones covered in the SDLogger code I found in the cookbook. Regarding initialisation, I am finding (as stated on the cookbook page) that the current code  from the mbed library doesn't work for all that many cards (including my SanDisk 2Gb standard SD and MicroSD). Due to my inexperience in interpreting such specs and novice programming skills I haven't yet been able to implement the rest of the initialisation tree such that my cards are rendered useful.

Any help with this would be much appreciated,

Sam

09 Sep 2010

Hi Sam,

Have you tried the library on the new cookbook:

Whilst it is still more of an experiment than a full implementation, I did extend it to cover more card types.

Simon

09 Sep 2010

Hi Simon,

I have my (based on your) code working fine if the SD card is in the slot, but if the card is not in the slot, or the card does not have the right file on it, I get error messages and the code hangs. Error messages are OK but the only way to get out of the hang is a re-boot.

Are there any low level calls I can make to (a) test the card is inserted, and (b) that the right file is on the card, without the code hanging?

Help would be appreciated

John

10 Sep 2010

Thanks Simon,

I had looked on that page but must have missed the recent update.

Once I add the new code (using a sanDisk 2Gb SD card) I'm getting:

Hello World!

No disk, or could not put SD card in to SPI idle state

Didn't get a response from the disk

Set 512-byte block timed out

Could not open file for write

Am I still just using the wrong card or have I missed something more fundamental? I'll give the 2Gb San Disk MicroSD a go too.

 

Thanks for your help.

 

Sam

 

12 Sep 2010 . Edited: 12 Sep 2010

Hi !

John, this code work on my mbed, i could check if a file exist or not

/** ----------------------------------------------------------------------
*    sdcardIsFileExist
*    Verifie si le fichier existe
*    In     : nom du fichier
*    Out    : true/false
* ---------------------------------------------------------------------*/
char sdcardIsFileExist(const char *fileName)
{

FILE *fpFileExist = fopen(fileName, "r");   
if(!fpFileExist)
{
#ifdef DEBUG_SDCARD
debugNewLine("file not exist");
#endif
return (false);
}

fclose(fpFileExist);
return (true);
}

But... it's working for a filename like /sd/src1/01-01-70.csv but mbed hang if i add an reference to a directory (the directory "src1" already exist on my SdCard) : /sd/src1/01-01-70.csv

Simon have you an idea ?

Thank you.

Chris

12 Sep 2010 . Edited: 28 Oct 2010

Hi again ;-)

some news...

After download the Simon's sample code, all works fine, why ? -> i used the old .cpp and .h files, now i import the SdFileSystem lib an it's fine.

I could test is an file exist or not even if the file is on subdir, great.

But i found a other issue when i want to write a file in a subdir. If my "isFileTest" test return false, i try to create a file on a subdir, and the mBed hang. If i try the same code in the root dir, all works fine (my original code write file only in the root dir).

I'm not sure it's an issue, but i find the "workaround".

If i try to create an new file in "append" mode in the root dir -> code is working, but if i try to do this in a subdir, the mBed hang.

I change my code to manage Append mode and Write mode, now i could create a new file in a sub file, i use Write mode to create it, after i could use Append mode to add data in my log file.

All works fine now with this "better" approach of file management on the SdCard.

Here my working code (trash and dirty for the moment sorry) :

#define WRITEFILE       1
#define APPENDFILE      2

/** ----------------------------------------------------------------------
*    sdcardWriteFile
*    Ecrit une trame dans le fichier specifie
*    In     : nom du fichier, mode d'ecriture, donnees a ecrire
*    Out    : true/false
* ---------------------------------------------------------------------*/
char sdcardWriteFile(const char *fileName, char mode, char *data)
{

FILE *fp2;
switch (mode)
{
case WRITEFILE :
fp2 = fopen(fileName, "w");
break;
case APPENDFILE :
fp2 = fopen(fileName, "a");       
break;
default:
fp2 = fopen(fileName, "w");
}

if(!fp2)
{
return (false);      
}
else
{
fprintf(fp2,data);
fclose(fp2);
}

return (true);
}

/** ----------------------------------------------------------------------
*    sdcardIsFileExist
*    Verifie si le fichier existe
*    In     : nom du fichier
*    Out    : true/false
* ---------------------------------------------------------------------*/
char sdcardIsFileExist(const char *fileName)
{

FILE *fp1 = fopen(fileName, "r");   
if(!fp1)
{
return (false);
}
else
fclose(fp1);

return (true);
}

Thanks again Simon for your SDFileSystem lib !

Chris

25 Jan 2011

Sorry to resurrect an old thread, but did anyone figure out a solution for detecting the presence of an SD card without hardware modification? I notice that the conversation changed to the topic of testing for files existing on an already inserted card.

05 Nov 2014

I know this is old but I was just struggling with this so I'm posting...

If a micro sd card is present it's SPI data output wire will be high by default... Simply test for this at the start of your program

DigitalIn sdmiso(P0_17);
printf("Booting... SD=%d\r\n",sdmiso);

SDFileSystem *sd = new SDFileSystem(P0_18, P0_17, P0_15, P0_19, "sd");

Hope that helps!

Jon MBED BASED SCADA ~ http://microhydroelectric.ca/store/internet-scada-rtu-monitoring