SD and SDfat compatibility

Fluxanode

Well-known member
I have a program that is written using SDfat. I'm trying to implement MTP Responder which uses SD and was told by @WMXT to use SD. I was told that SD is now the same as SDfat(https://forum.pjrc.com/threads/43050-MTP-Responder-Contribution/page39) but if I simply change #include "SdFat.h" to #include "SD.h" I now get a file open error when creating or opening a file for writing. The sd.begin() seems to work and returns that the function completed successfully. My program compiles without any error messages.

My initialization:

Code:
//Setup for SdFat lib *************************************
//#include "SdFat.h"
#include "SD.h"
#define USE_EXTERNAL_SD                //Comment out if using internal SD card
#ifdef USE_EXTERNAL_SD
const uint8_t SD_CS_PIN = SS;
#define SPI_CLOCK SD_SCK_MHZ(10)
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI, SPI_CLOCK)
#else // Use built in SD card.
#ifdef SDCARD_SS_PIN
const uint8_t SD_CS_PIN = SDCARD_SS_PIN;
#endif // SDCARD_SS_PIN
// Setup for built in SD card.
#define SPI_CLOCK SD_SCK_MHZ(50)
#define SD_CONFIG SdioConfig(FIFO_SDIO)
#endif // USE_EXTERNAL_SD

SdFs sd;                               // SdFat usage 
FsFile myFile;

File open and write:
Code:
        String time = GetTimeNow();                               //get the datetime, store in var time
        Serial.print("Attempting Open file- ");                   //print to Serial open file msg
        filename = get_Date();                                    //get the date for the file name
        filename += ".txt";                                       //make the file name (date + .txt)
        Serial.println(filename);                                 //print the file name to Serial
        Serial.println(GetTimeNow());

        myFile = sd.open(filename.c_str(), FILE_WRITE);           //open the SD file for writing
        if (myFile) {                                                                //if file opened okay, write to it
            myFile.print(time);                                                  //print the time to SD
            myFile.println(s3);                                                  //on the same line print the csv data string + crlf
            myFile.close();                                                       //close the file on SD
            Serial.println("File write done.");                             //Serial print "done" if no errors
            Serial.println("");
        }
        else {
            Serial.println("SD Card Error");
            Serial3.println("SD Card Error");
            Serial3.print("error opening- ");                    //else, if the file didn't open, print an error msg
            Serial3.println(filename);                             //with the file name on Serial3                                    
        }

What do in need to change to correct the file open?
Is the SD lib included with Arduino / Teensyduino the same as the Greiman Git version SDfat?
 
@Fluxanode - You are mixing the two different API's in the wrong way. SD wraps SdFat. You need to use one or the other. I would suggest that you check the examples in the SD library first. In particular the 'Files.ino' example. Based on your example code it will not work. After that I would suggest looking at the examples in the SdFat library for the alternate ways to access and use SdFat separately from SD.
 
You can mix the SD and SdFat APIs.

But not like this:

Code:
SdFs sd;                               // SdFat usage

You need to use "SD.sdfs" to access the instance created by the SD library. The code you showed should work if you simply delete that line and replace all "sd" with "SD.sdfs", so everything is using the 1 instance of SdFat created by using SD.h.

In Arduino, click Files > Exmaples > SD > SdFat_Usage for an example. See the comments within that example code for an explanation of how it works.
 
@Paul et all, what is the equivalent SD fat version of this line myFile = sd.open(filename.c_str(), FILE_WRITE); which will create a file and write to it if it does not exist or open the file for writing if it exists? This line (myFile = SD.sdfs.open(filename.c_str(), O_WRITE | O_CREAT);) seems to only create the file and write to it, and if it exists it wipes it out and and remakes the file. In other words it does not open simply for writing.

I there a reference with the file create, read, write open, close... options defined that i can refer to like the arduino https://www.arduino.cc/en/reference/SD reference pages?
 
@Paul et all, what is the equivalent SD fat version of this line myFile = sd.open(filename.c_str(), FILE_WRITE); which will create a file and write to it if it does not exist or open the file for writing if it exists? This line (myFile = SD.sdfs.open(filename.c_str(), O_WRITE | O_CREAT);) seems to only create the file and write to it, and if it exists it wipes it out and and remakes the file. In other words it does not open simply for writing.

I there a reference with the file create, read, write open, close... options defined that i can refer to like the arduino https://www.arduino.cc/en/reference/SD reference pages?

Here I go again sticking my nose in again:) Correct me if I am wrong but is sounds like you are trying to add data to the end of the file. If you use O_CREAT it will create the file if it does not exist or set the write position to the beginning of the file if it does exist. If you want to add data to the end of the file you should use:
Code:
myFile = SD.sdfs.open(filename.c_str(), O_WRITE | O_APPEND)
This does not recreate the file. But adds any data written to the file to the end of the file.

For reference:
https://forum.arduino.cc/t/sdfat-do-not-overwrite/373174

Example sketch:
https://www.if.ufrj.br/~pef/producao_academica/artigos/audiotermometro/audiotermometro-I/bibliotecas/SdFat/Doc/extra/examplesV1/SdFatAppend/SdFatAppend.ino

Also, the HTML reference to SdFAT can be found here:
https://github.com/greiman/SdFat/tree/master/doc
 
Last edited:
wwatson thanks for sticking your nose in, I was hoping to to have the functionality of file_write where it could create the file if it didn't exist and write to it, or append to the end if it does exist.
 
wwatson thanks for sticking your nose in, I was hoping to to have the functionality of file_write where it could create the file if it didn't exist and write to it, or append to the end if it does exist.

Make a call to see if it exists & if so, use the O_APPEND flag, otherwise (does not exist) use the O_CREATE flag ??

Mark J Culross
KD5RXT
 
For the records:
the TD implementation of SD has two definitions
FILE_WRITE :create,open,append
and
FILE_WITE_BEGIN: create,open,rewind

Note: The SdFat definition of FILE_WRITE is undefined in SD.h
 
What is the test for if a file exists?

BTW the documentation provided is not very user friendly.
I would be cool if there was a simple usage file or page with the most used functions listed and their arguments. As is documented for SD on Arduino https://www.arduino.cc/en/reference/SD.

in case you have not found it not youself, SD.h says
Code:
	bool exists(const char *filepath) {
		return sdfs.exists(filepath);
	}
 
Back
Top