SdFat update

A new version of SdFat, sdfatlib20120719.zip, is available here Google Code Archive - Long-term storage for Google Code Project Hosting..

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 Arduino style SdFat::begin(chipSelect, spiSpeed);

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.

Thank you for your great library,
Mark

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

Hi fat16lib,

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.

Again thanks!

SdFat has been totally rewritten since the version used with the SD.h wrapper so it is not practical to update the version of SdFat used in SD.h.

The Arduino company is responsible for SD.h and has never contacted me so I don't know if they have plans to update to the new SdFat.

hello, I have one problem using Sdfat.h

I can not use 1.1 V like reference in Sdfat.h, although I select "(1 << REFS1) | (1 << REFS0)" I measure that the reference used is 5V.

Please help me,
I am using the latest version of the SDfat.h library on arduino ONE. thank you!

I can not use 1.1 V like reference in Sdfat.h, although I select "(1 << REFS1) | (1 << REFS0)" I measure that the reference used is 5V.

SdFat has nothing to do with the ADC.

How are you setting the reference voltage?

Did you call analogReference(INTERNAL) ? You can't use "(1 <<REFS1) | (1 << REFS0)" in this call.

I'm Trying to use the sketch proposed here:

http://forums.adafruit.com/viewtopic.php?f=31&t=30557

in that skecth exist the following lines:

// Reference voltage
// Zero - use External Reference AREF
// (1 << REFS0) - Use Vcc
// (1 << REFS1) | (1 << REFS0) - use Internal 1.1V Reference
uint8_t const ADC_REF_AVCC =(1 << REFS1) | (1 << REFS0);

So I think that the use of "(1 << REFS1) | (1 << REFS0)" will reference the ADC to 1.1 V.

Sorry if I'm posting in the wrong place, I'm new. Greetings from Chile!

Using Analogreference(INTERNAL) and the option "(1 << REFS1) | (1 << REFS0)" the analogread works between 0 - 1.1V ! thaks !

Hi fat16lib,

I have a problem posted here ([SOLVED] Problem data logging with TinyGPS++ and SdFat - Storage - Arduino Forum) involving SdFat and other libraries, Any insight would be highly appreciated.

Regards.

Hi,

there are so many versions.. may someone tell me, which one is the newest stable version.. :expressionless:

Greetz Chris

The current stable version is sdfatlib20131225.zip Google Code Archive - Long-term storage for Google Code Project Hosting..

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 will move to GitHub.

Ok, thank you.

Greetz Chris

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>

You must have an ancient version of SdFat. WProgram.h was removed from the Arduino IDE years ago. Use this version of SdFat GitHub - greiman/SdFat: Arduino FAT16/FAT32 exFAT Library

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

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'.

Try the SdFat beta here GitHub - greiman/SdFat-beta: Beta SdFat for test of new features.

This version of SdFat has an untested extension of SdFile to Arduino Streams so parseInt() should be supported.

Let me know if it works or if there is a problem.

Hi, thanks for a quick response.

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.