This version requires Arduino version 1.0 or greater since implementing and testing new features in older versions is time consuming and messy.
Here are some of the additions/changes:
Added support for SDXC cards formatted as FAT32. Modified the SdFormatter
example to format SDXC cards as FAT32. This is not the SDXC standard which
is exFAT.
Added options for SD crc checking. Enabling crc checking increases reliability
at the cost of speed. Edit SdFatConfig.h to select CRC options.
Added << operator for Arduino flash string macro F().
New RawWrite example for fast write of contiguous files.
New faster software SPI
Software SPI for Leonardo boards
Changes to allow use of the SerialPort library.
Error messages and output from programs are now sent to a stdOut Print
stream.
The default stdOut is a small non-interrupt driven class that outputs messages
to serial port zero. This allows an alternate Serial library like SerialPort
to be used with SdFat.
You can redirect stdOut with SdFat::setStdOut(Print* stream) and
get the current stdOut stream with SdFat::stdOut().
Change file type for all examples to *.ino.
Removed __cxa_pure_virtual to avoid conflicts with other libraries.
Thank you for the continued support of SDcard storage! I have been using your library with the "' << operator" and have found it to very helpful for saving varying types of data.
Is there a fairly simple code to allow me to clear or erase the SDcard with the Arduino? In my case, I am making a logger and I might want to restart the log session. I would like to do a quick erase of the card so that all of the data on the card will pretain to one log session. I was thinking the older SDFat library had that feature but, if I had the sketch I lost it.
I am aware of the sd formatter sketch but, it looks like it has a lot of extra features that I do not need.
SdFat has a function, rmRfStar(), that will clean an SD. Here is the documentation:
bool SdBaseFile::rmRfStar()
Recursively delete a directory and all contained files.
This is like the Unix/Linux 'rm -rf *' if called with the root directory hence the name.
Warning - This will remove all contents of the directory including subdirectories. The directory will then be removed if it is not root. The read-only attribute for files will be ignored.
Note:
This function should not be used to delete the 8.3 version of a directory that has a long name.
Returns:
The value one, true, is returned for success and the value zero, false, is returned for failure.
Here is an example sketch that will delete all except the root directory:
#include <SdFat.h>
SdFat sd;
void setup() {
Serial.begin(9600);
Serial.println("Type any character to delete all files");
while (Serial.read() <= 0) {}
if (!sd.begin()) sd.initErrorHalt();
// list all files
sd.ls(LS_R);
// sd.vwd() is root, working directory for volume
// remove all files and directories in root
sd.vwd()->rmRfStar();
Serial.println("---------- rmRfStar()");
sd.ls(LS_R);
Serial.println("Done");
}
void loop() {}
Here is output from the sketch using an SD with two directories and a file.
Type any character to delete all files
DIR2/
DIR3/
NAME3.TXT
---------- rmRfStar()
Done
Thanks fat16lib for providing with your wonderful code! Sorry I took so long, I finally got a chance to test your SD card erase function.
I started by check for data on the card...I had several files. Then, I added chipselect, and SPI_FULL SPEED.
I ran the sketch with results similar to the output you described. I then tested the card with the computer and Yes indeed the card was clear!!!
Here is the serial output....
Type any character to delete all files
LOGGER00.CSV
LOGGER01.CSV
LOGGER02.CSV
LOGGER03.CSV
LOGGER04.CSV
LOGGER05.CSV
LOGGER06.CSV
LOGGER07.CSV
LOGGER08.CSV
LOGGER09.CSV
LOGGER10.CSV
LOGGER11.CSV
---------- rmRfStar()
Done
first of all i would like to say that your library is absolutely fantastic and helped me achieve the 200Hz logging speed i required by modifying the RawWrite function.
However I am writing to write to 2 files in my program; one for calibration and one for logging data. I have figured out how to not overwrite the data I have already stored in the files but I am having trouble properly closing the contiguous files that are created so that i can open them up again to log data when necessary.
It seems that if your RawWrite example in the new library and the old library you were just deleting the old file by using the sd.remove("RAW.TXT") or SdFile::remove(&root, "RAW.TXT"). I am not sure if the closing the file with file.close(); or root.close() and file.close() is the right way to close the contiguous file. Could you please help with this? currently when I try to write to the file again I get an error saying i cant create the contiguous file again.
Thanks in advance for anyone who can help with this.
P.S. Thank you also for your advice in older forums about not purchasing expensive SD cards. I am getting write time of 800 microsecs by using a 2GB transcend SD card from JayCar electronics.
It shouldn't matter how you close the file. You can close the file before calling Sd2Card::writeData(). That's what raw write means. You are writing directly to the SD by raw block address.
You can reopen the file with open() and find the location of the file's blocks with contiguousRange().
The problem is knowing where to start writing. You need to keep track of the last block written in the file and start at that position. You could rewrite the first block of the file with that type of info or write the last block address to another file.
Again, as others have said, thanks for the very useful library and all the work that entails.
Since the Arduino IDE has an included SD.h that is a wrapper to SdFat, what is the best way to upgrade completely?
I put the SdFat library in the Arduino/libraries directory and that worked great. Until I tried to use a library that includes SD.h (IniFile).
I'm hoping there's a way to swap in the new SdFat into the SD's utility folder but I suspect the wrapper needs to be updated. Is that correct? Is there an updated SD.h to replace the core lib from Arduino 1.0?
I happen to be on a Mac so currently I have the following structure in the Arduino package:
Arduino/Contents/Resources/Java/libraries/SD/utility/(all the SdFat.h's and .cpp's)
(edit sorry forgot Java in the path)
Replacing the contents of utility with the latest SdFat files doesn't work.
I won't be updating the Google site since Google no longer allows downloads:
Existing projects with downloads will see no visible changes until January 14, 2014 and will no longer have the ability to create new downloads starting on January 15, 2014.
I'm having trouble using this, I keep getting errors:
In file included from microSD.ino:13:0:
/home/tony/Arduino_projects/libraries/SdFat/SdFatUtil.h:27:22: fatal error: WProgram.h: No such file or directory #include <WProgram.h>
Hi I'm trying to convert a large sketch (30+k) on an UNO from the Standard SD to the Sdfat Library because I need to be able to rename some files periodically. I'm hoping to save some space in the process.
Unfortunately my SD based sketch, which is a mix of data logger and web server, uses the following snippet code to first trap a '$' sign in the HTML file being sent out for a replacable value
while (outputFile.available()){ //read the file untill its all gone
c = outputFile.read(); //get a character
if (c != 36) { //we havent found the replacement '$' flag
Buffer = c; //add the current character to the string
i++; // increment place*
}//end if !'$'*
if ((i == (BUFFER_LEN-1)) || (c =='\n') || (c == 36)){ //all cases for sending what we'ev got*
_ Buffer = 0; // teminate the string_ _ client.print((char*)Buffer); // send it to client_ * i=0; //just to be sure* * memset(Buffer, 0 ,sizeof(Buffer)); //clear the Buffer* * }* * if (c == 36){ // it was the replace character* * c = outputFile.read(); //get the next one to determin which number to send* * j = outputFile.parseInt(); //get next char which should be pointer to value & convert to No.* * if (j < 0 || j > 24){ //limit valid range* * //client.print(F("Illegal"));* * }* * else { //legal replacement value* * switch (c){* * case 70: //found 'F' for file* * breakTime(systime);* * switch (j){ //now what type of file is wanted* * case 0:* * client.print (dateTime);* _ //memcpy((char*) Buffer , dateTime , 11); //tell the web system date & time_ * //i = 11;* * break;* * case 1:* * client.print (fileName);* _ //memcpy((char*) Buffer , fileName , 12); //tell web current data file name_ * //i = 12;* * break;* * case 2:* * if (TickTock[6]){ //Warning*
* client.print (F("NTP Time Sync Lost - Reboot Controller"));* _ //memcpy((char*) Buffer , msg1 , 38);_ * //i = 38;* * }* * break;* * case 3:* * ListFiles(); //list all the datfiles on the system* * break; * * }//end switch [j]*
* break;//end case70* * case 83: // found 'S' for set point* * client.print((float)SetPoints[j],1);//Float to get decimal point in output* * break;* * case 84: // found 'T' for Temperature* * client.print(convert2T(readings[j]),1); //Absolute temperature* * break;* * case 85: // found 'U' for Transfercurve points* * client.print((float)TCTemps[j],1); //Byte might be -ve. float handles decimal point* * break;* * case 88: // found 'X' for relay status* * switch (j){* * case 3:* * client.print((temperatureRising[j])? (F("CLOSED")):(F("OPEN and will call gas boiler for heat")));* * break;*
* case 5:* * client.print((temperatureRising[j]) ? (F("Secondary")):(F("Main")));* * break; * * }* * break;//end case 88 open/closed direction statements* * } //end case for get variables* * } //end else* * }//ends if (c ==36...* * }//end while* having trapped the '$' it uses the c = outputFile.read(); //get the next one to determin which number to send j = outputFile.parseInt(); //get next char which should be pointer to value & convert to No to work out which number to send out to the web page. Trouble is I don't see the equivalent of the 'parseInt' functionallity in SdFat. Ultimately 'j' needs to get up to two digits so I need to do more than just read the the next charachter in the the 'outputFile'. Help and pointers in the right direction would be welcome
c = outputFile.read(); //get the next one to determin which number to send
j = outputFile.parseInt(); //get next char which should be pointer to value & convert to No
to work out which number to send out to the web page. Trouble is I don't see the equivalent of the 'parseInt' functionallity in SdFat. Ultimately 'j' needs to get up to two digits so I need to do more than just read the the next charachter in the the 'outputFile'.
I've downloaded the beta version but the IDE (1.0.5) is still falling over on the 'j= outputFile.parseInt();' with the error
SendFile:50: error: 'class SdFile' has no member named 'parseInt'
Output file is declared as
SdFile outputFile;
at the beginning of this function. I've not yet declared any arduinostreams though I was leaving that change until later to see if it would neaten up the outputs and save space.