SdFat update

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.

Try running this:

#include <SdFat.h>
SdFat sd;
SdFile file;

const uint8_t csPin = 10;
void setup() {
  Serial.begin(9600);
  Serial.print(F("Version: "));
  Serial.println(SD_FAT_VERSION);
  if (!sd.begin(csPin)) sd.initErrorHalt();
  if (!file.open("stream.txt", O_RDWR|O_CREAT|O_TRUNC)) {
    Serial.println(F("open error"));
  }
  file.println("12324");
  file.rewind();
  int i = file.parseInt();
  Serial.println(i);
  file.close();
}

void loop() {}

The output should be:

Version: 20141023
12324

Hi fat16lib,

When you were on google code, there was an very handy doxygen user-guide, any plans to have an updated version of that on your git repository?

Regards,

Graham

The doxygen is here https://github.com/greiman/SdFat/tree/master/html.

Click on SdFat.html to read it.

Great! Thankyou.

Regards,

Graham

Hi, Run the code and the version is showing as 20141023! so I've got the right version of the beta

I've done a quick workaround on the 'parseInt' issue and temporarlly disabled that requirement to see if I can get the rest working but I cant even open the file I want to send!

The beginning of this function I'm working on starts

void sendFile(char thisFile[])
{
//const char msg1[39] = "NTP Time Sync Lost - Reboot Controller";

const byte BUFFER_LEN = 48; //TC/IP Output buffer
byte Buffer[BUFFER_LEN];
byte j = 0; //Web Variable suffix
byte i = 0; //counter for working through outputFile
char c; //for getting character from file
SdFile outputFile;

Serial.println(thisFile);
client.print(F("HTTP/1.1 ")); //common header start
///File outputFile = SD.open(thisFile); //open the file for reading
if (!outputFile.open(thisFile,O_READ)) {
Serial.println("about to send");

'thisFile' is the 8.3 name of the file I want to send out when the routine is called

outputFile is declared as an SdFile object

But it never opens or sends and it's on the SD card!

I'm probably getting the syntax of SdFat wrong but where is not obvious

the SD.begin is in the setup

//Check presence of SD card
if (!sd.begin(sdChipSelectPin, SPI_HALF_SPEED)) sd.initErrorHalt();
/////////////////////////////////

I've tried other Example sketches (changing the CS pin to 4) and they all behave so there isn't a problem with the card or the Ethernet shield.

I'm probably getting the syntax of SdFat wrong but where is not obvious

First try running this program that tests parseInt. It works for me so let's make sure it works in your setup. I have changed the chip select pin to 4 and tested it with an Ethernet shield. I also attached the program as a file. You will need to change the file type from .txt to .ino.

Please download the latest SdFat beta since I made a few changes and included a new example, StreamParseInt.ino GitHub - greiman/SdFat-beta: Beta SdFat for test of new features

#include <SdFat.h>
SdFat sd;
SdFile file;

const uint8_t csPin = 4;
const uint8_t enPin = 10;

void setup() {
  Serial.begin(9600);
  
  // Print SdFat version
  Serial.print(F("Version: "));
  Serial.println(SD_FAT_VERSION);
  
  // Disable the W5100.  Not really needed for Uno.
  pinMode(enPin, OUTPUT);
  digitalWrite(enPin, HIGH);
  
  // Initialize the SD.
  if (!sd.begin(csPin)) {
    Serial.println(F("begin error"));
    return;
  }
  // Create and open the file.
  if (!file.open("stream.txt", O_RDWR|O_CREAT|O_TRUNC)) {
    Serial.println(F("open error"));
    return;
  }
  // Write a test number.
  file.println("12345");
  
  // Rewind the file and read the number.
  file.rewind(); 
  int i = file.parseInt();
  Serial.print(F("Test Number: "));
  Serial.println(i);
  file.close();
}

void loop() {}

Here is the output:

Version: 20141023
Test Number: 12345

StreamTest.txt (818 Bytes)

Interestingly I got the Stream test to work first time with the original SdFat using IDE 1.0.5

I then went back to my sketch and discovered some syntax problems and got that working as well using the original SdFat under 1.0.5

I then moved on to IDE 1.0.6 and the compile fell over on the parseInt again. Dragging the first beta of SdFat into the 1.0.6 libraries allowed the sketch to compile albeit that it is now 26700 bytes as opposed to 26500 bytes under 1.0.5. Both a lot better than 30100bytes under 1.0.4 with the standard SD.

At what point do you think that you will have finished the Beta of the new SdFat?

At what point do you think that you will have finished the Beta of the new SdFat?

I was about to move the beta to the release version but it will now be a bit longer.

SD.h is just a wrapper for a really old version of SdFat. I have been meaning to add a compatibility API to make it easy to convert from SD.h to SdFat. Your post caused me to look at this again.

I spent about two hours writing a new Arduino SD.h style File class that has SdFile as a parent and added a SD.h style open. It was amazingly easy.

I tested it with each of the SD.h examples. You just do the following to convert from SD.h to SdFat.

// comment out this
// #include <SD.h>

// and add these two lines
#include <SdFat.h>
SdFat SD;

All of the examples in the SD.h library work. My File class has all the SdFile member functions in addition to the standard File class member functions.

Since SD is now a modern SdFat, things like rename() and ls() work.

I will need to find some testers to verify other SD.h code works and SdFat code still works.

I want to do a little more testing and then I will make this the new beta.

Great looks as though the two are coming back together again.

I'll press on with the other things that I've got to do with my code for now.

Thanks for your help.

Has anyone been able to run the bintocsv.exe file included in the utilities directory successfully? I get an error that says "The program can't start because MSCR100D.dll is missing from your computer...." I am attempting to run this on a W7 machine. A brief search indicated the error may be related to not having Visual Studio installed. Is this the case? Is there some other workaround? I am assuming this *.exe is used to convert a *.bin file on the pc. Please correct me if I've got that wrong.
Thanks for you help, and the great library.

You need the VC++ 2010 run-time components http://www.microsoft.com/en-us/download/details.aspx?id=8328.

bintocvs will convert the .bin file for the unmodified example. If the example is modified, you will need to modify and rebuild bintocsv.

Bill, I just thought I'd give you a little feedback, in case you don't have a mega1284 board. Been trying your new SdFat and SdFat_beta libraries with an older WinXP notebook PC, IDE v1.0.5, and a mega1284 board with pinout almost identical to the Bobuino [I patched DigitalPin.h for the changed pins].

[aside: BTW, you might note that the SdFat library only has the Mighty-1284 variant and doesn't have Bobuino or any others, but SdFat_beta is inclusive].

Also, I am attempting to use SD with an RFM12 radio on the same board, and have had some SPI conflicts. Haven't resolved this as yet, but will provide an update once I know more.

In any case, so far so good with the testing. Here are some results to look at, using SdFat_beta examples. It deals nicely with truncating overly-long file names, and the file sizes all look correct. I also added the RAM display routine.

SdInfo example - 8GB SD card:
avrdude: 13026 bytes of flash verified

-SRAM left: 15398
SdFat version: 20141025

type any character to start

init time: 14 ms

Card type: SDHC

Manufacturer ID: 0X3
OEM ID: SD
Product: SL08G
Version: 8.0
Serial number: 0X98BE190E
Manufacturing date: 7/2014

cardSize: 7948.21 MB (MB = 1,000,000 bytes)
flashEraseSize: 128 blocks
eraseSingleBlock: true
OCR: 0XC0FF8000

SD Partition Table
part,boot,type,start,length
1,0X0,0XB,8192,15515648
2,0X0,0X0,0,0
3,0X0,0X0,0,0
4,0X0,0X0,0,0

Volume is FAT32
blocksPerCluster: 64
clusterCount: 242304
freeClusters: 242171
freeSpace: 7935.46 MB (MB = 1,000,000 bytes)
fatStartBlock: 12596
fatCount: 2
blocksPerFat: 1894
rootDirStart: 2
dataStartBlock: 16384

type any character to start

QuickStart example:
avrdude: 18782 bytes of flash verified

-SRAM left: 15283
SPI pins:
MOSI: 11
MISO: 12
SCK:  13

SD chip select is the key hardware option.
Common values are:
Arduino Ethernet shield, pin 4
Sparkfun SD shield, pin 8
Adafruit SD shields and modules, pin 10

Enter the chip select pin number: 8

Disabling SPI device on pin 10

Card successfully initialized.

Card size: 7948 MB (MB = 1,000,000 bytes)

Volume is FAT32, Cluster size (bytes): 32768

Files found (name date time size):
DATA1030.LOG   2014-11-01 12:33:36 17
TEST1.TXT      2000-01-01 01:00:00 54
DATA1014.LOG   2000-01-01 01:00:00 32
IMAGES/        2014-11-06 13:16:42
  LION3.BMP      2013-10-20 22:46:48 97254
  SIM_0108.JPG   2011-08-01 11:10:14 208312
  TACHIK~1.JPG   2011-06-30 17:26:16 29867
OTHER/         2014-11-06 13:16:52
  PIC32M~1.PDF   2009-12-16 19:43:20 3250560
  AN1140~1.PDF   2009-12-16 19:53:22 478223
TEST0924.TXT   2000-01-01 01:00:00 2016

Success!  Type any character to restart.

I did see one funny thing, with SanDisk 4GB card, it indicates the manufacture date was in 2002. Didn't think they even had SD cards back then, plus I'm sure I bought this card not too long ago, so ??

-SRAM left: 15398
SdFat version: 20141025

type any character to start

init time: 681 ms

Card type: SDHC

Manufacturer ID: 0X3
OEM ID: SD
Product: SU04G
Version: 8.0
Serial number: 0X4B130102
Manufacturing date: 4/2002

cardSize: 3965.19 MB (MB = 1,000,000 bytes)
flashEraseSize: 128 blocks
eraseSingleBlock: true
OCR: 0XC0FF8000

SD Partition Table
part,boot,type,start,length
1,0X0,0XB,8192,7736320
2,0X0,0X0,0,0
3,0X0,0X0,0,0
4,0X0,0X0,0,0

Volume is FAT32
blocksPerCluster: 64
clusterCount: 120752
freeClusters: 120727
freeSpace: 3955.98 MB (MB = 1,000,000 bytes)
fatStartBlock: 14496
fatCount: 2
blocksPerFat: 944
rootDirStart: 2
dataStartBlock: 16384

type any character to start

Also, I am attempting to use SD with an RFM12 radio on the same board, and have had some SPI conflicts. Haven't resolved this as yet, but will provide an update once I know more.

FWIW, I think I've got this resolved now, by taking a very conservative approach.

I am so far using the IDE v1.0.5 SD library with Sd2PinMap.h patched to provide support for the Bobuino and mega1284 chip. Will eventually go to using the SdFat libraries.

In my largish sketch [29.9KB on the mega1284], I was able to resolve the conflicts between the RFM12 radio and SD.

  1. first, both RFM12 and SD appear to use the same SPI mode, etc.

  2. changed to doing the setup for the SD card first before the radio, as there was
    some indication in the notes that it uses a slow SPI bitrate during initialization.

  3. added the releaseMISO() code, as discussed earlier, at the end of SD operations.

  4. I still seemed to need to add a deassert_sdCS() prior to doing any radio operations,
    it's at least for good certainty.

At least it all seems to work now, so good for getting something resolved.