Go Down

Topic: SdFat update (Read 10 times) previous topic - next topic

Chris72622

Ok, thank you.

Greetz Chris
https://github.com/jeffThompson/DarkArduinoTheme

fat16lib

Quote

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 https://github.com/greiman/SdFat

solar_eta

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

fat16lib

Quote
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 https://github.com/greiman/SdFat-beta.

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.

solar_eta

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.


fat16lib

#20
Oct 23, 2014, 09:13 pm Last Edit: Oct 23, 2014, 09:17 pm by fat16lib
Try running this:
Code: [Select]

#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:
Quote
Version: 20141023
12324

ghlawrence2000

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

fat16lib

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

Click on SdFat.html to read it.

ghlawrence2000

Great! Thankyou.

Regards,

Graham

solar_eta

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

solar_eta

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.





fat16lib

#26
Oct 24, 2014, 01:44 pm Last Edit: Oct 24, 2014, 05:10 pm by fat16lib
Quote
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 https://github.com/greiman/SdFat-beta
Code: [Select]

#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:
Quote
Version: 20141023
Test Number: 12345

solar_eta

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?

fat16lib

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

Code: [Select]

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

Go Up