Uploading a file from st card to FTP server

I am just wondering what is the best/easiest way of uploading a file to an FTP server using the SDfat Library

what I would like to do is upload a log text file that stored in the root of the SD card and is name for eg (unit 1000 / month02/ day15) 10000215.txt and or CSV ( don't really care)

but what I would like to do is :-

  1. Check for a server connection ever 15 mins
  2. Connect with user name and password
  3. check if file exists if not upload
  4. if file does amend.
  5. on successful upload delete file if not equal to current file name.

i would prefer to use FTP I have tried to convert this code to make it work with SDfat but with no luck
http://playground.arduino.cc//Code/FTP

I could use a PHP script and get that to do the upload my issues is if the file get to big having issues uploading it.
http://arduino.cc/forum/index.php/topic,40295.0.html

Any suggestions how I can do this effectively are more than welcomed. welcomed.

i would prefer to use FTP I have tried to convert this code to make it work with SDfat but with no luck

Code changes are not a matter of luck. Post YOUR code, with changes, and describe what happened when you ran the code.

I wrote the FTP client sketch. It should not be that difficult to convert. Isn't that SDfat library written by fat16lib? The hard part was getting two sockets open and working, not the SD read and write.

Okay here is what I have got to when I run it up I get it to look like it connecting but then nothing I think I need a time out value some where to say if it has not connected it will fail the connection.

Type any character to start
Done - check on the SD
1Type any character to start
Done - check on the SD
2Type any character to start
Done - check on the SD
3Type any character to start
Done - check on the SD
4Type any character to start
Done - check on the SD
5Type any character to start
Done - check on the SD
6Type any character to start
Done - check on the SD
7Type any character to start
Done - check on the SD
8Type any character to start
Done - check on the SD
9Type any character to start
Done - check on the SD
10Type any character to start
Done - check on the SD
Start FTP UploadSD opened
Command connected

#include <SdFat.h>
#include <SdFatUtil.h>
#include <Ethernet.h>
#include <SPI.h>


#define FTPWRITE

// this must be unique
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x59, 0x67 };  
// FTP Server name
char serverName[] = "update.ftpsever.com";
//FTP Stuff
EthernetClient client;
EthernetClient dclient;
char outBuf[128];
char outCount;
char fileName[13] = "10001602.TXT";

// FTP Wait time
int FTPWait[1];

// change to your network settings
IPAddress ip( 192, 168, 3, 177 );    
IPAddress gateway( 192, 168, 3, 254 );
IPAddress subnet( 255, 255, 255, 0 );

// SD chip select pin
const uint8_t chipSelect = SS;

// file system object
SdFat sd;
SdFile fh;

// define a serial output stream
ArduinoOutStream cout(Serial);
//------------------------------------------------------------------------------
/*
 * Append a line to LOGFILE.TXT
 */
void logEvent(const char *msg) {
  
  // create or open a file for append
  ofstream sdlog("10001602.TXT", ios::out | ios::app);

  // append a line to the file
  sdlog << msg << endl;

  // check for errors
  if (!sdlog) sd.errorHalt("append failed");

  sdlog.close();
}
//------------------------------------------------------------------------------
void setup() {
  Serial.begin(9600);

  if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt();

  // append a line to the logfile
  logEvent("Sytem Started");

 }
//------------------------------------------------------------------------------
void loop() {
  // pstr stores strings in flash to save RAM
  cout << pstr("Type any character to start\n");
//  if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt();

  // append a line to the logfile
  logEvent("Another line for the logfile");

  cout << "Done - check on the SD" << endl;
  
if (FTPWait[0] == 10)
{     
Serial.print("Start FTP Upload");

  if(doFTP()) Serial.println("FTP OK");
    else Serial.println("FTP FAIL");
 
 
 FTPWait[0] = FTPWait[0] = 0;// resset FTP count
} 
  
FTPWait[0] = FTPWait[0] + 1 ;  


Serial.print(FTPWait[0]);


   
     delay(1000);  
}


//************************** FTP ********************

byte doFTP()
{
#ifdef FTPWRITE
  ifstream sdin(fileName);
  if (!sdin.is_open());
#else
  sd.remove(fileName);
#endif


#ifndef FTPWRITE  
  if(!fh.seek(0))
  {
    Serial.println("Rewind fail");
    fh.close();
    return 0;    
  }
#endif

  Serial.println("SD opened");

  if (client.connect(serverName,21)) {
    Serial.println("Command connected");
  } 
  else {
    fh.close();
    Serial.println("Command connection failed");
    return 0;
  }

  if(!eRcv()) return 0;

  client.write("USER username\r\n");

  if(!eRcv()) return 0;

  client.write("PASS password\r\n");

  if(!eRcv()) return 0;

  client.write("SYST\r\n");

  if(!eRcv()) return 0;

  client.write("PASV\r\n");

  if(!eRcv()) return 0;

  char *tStr = strtok(outBuf,"(,");
  int array_pasv[6];
  for ( int i = 0; i < 6; i++) {
    tStr = strtok(NULL,"(,");
    array_pasv[i] = atoi(tStr);
    if(tStr == NULL)
    {
      Serial.println("Bad PASV Answer");    

    }
  }

  unsigned int hiPort,loPort;

  hiPort = array_pasv[4] << 8;
  loPort = array_pasv[5] & 255;

  Serial.print("Data port: ");
  hiPort = hiPort | loPort;
  Serial.println(hiPort);

  if (dclient.connect(serverName,hiPort)) {
    Serial.println("Data connected");
  } 
  else {
    Serial.println("Data connection failed");
    client.stop();
    fh.close();
    return 0;
  }

#ifdef FTPWRITE 
  client.write("STOR ");
  client.println(fileName);
#else
  client.write("RETR ");
  client.println(fileName);
#endif

  if(!eRcv())
  {
    dclient.stop();
    return 0;
  }

#ifdef FTPWRITE
  Serial.println("Writing");

  byte clientBuf[64];
  int clientCount = 0;

  while(fh.available())
  {
    clientBuf[clientCount] = fh.read();
    clientCount++;

    if(clientCount > 63)
    {
      Serial.println("Packet");
      dclient.write(clientBuf,64);
      clientCount = 0;
    }
  }

  if(clientCount > 0) dclient.write(clientBuf,clientCount);

#else
  while(dclient.connected())
  {
    while(dclient.available())
    {
      char c = dclient.read();
      fh.write(c);      
      Serial.write(c); 
    }
  }
#endif

  dclient.stop();
  Serial.println("Data disconnected");

  if(!eRcv()) return 0;

  client.write("QUIT\r\n");

  if(!eRcv()) return 0;

  client.stop();
  Serial.println("Command disconnected");

  fh.close();
  Serial.println("SD closed");
  return 1;
}

byte eRcv()
{
  byte respCode;
  byte thisByte;

  while(!client.available()) delay(1);

  respCode = client.peek();

  outCount = 0;

  while(client.available())
  {  
    thisByte = client.read();    
    Serial.write(thisByte);

    if(outCount < 127)
    {
      outBuf[outCount] = thisByte;
      outCount++;      
      outBuf[outCount] = 0;
    }
  }

  if(respCode >= '4')
  {
    efail();
    return 0;  
  }

  return 1;
}


void efail()
{
  byte thisByte = 0;

  client.write("QUIT\r\n");

  while(!client.available()) delay(1);

  while(client.available())
  {  
    thisByte = client.read();    
    Serial.write(thisByte);
  }

  client.stop();
  Serial.println("Command disconnected");
  fh.close();
  Serial.println("SD closed");
}

void readSD()
{
 ifstream sdin(fileName);
  if (!sdin.is_open());

  //if(!fh) // error need to look at
  //{
   // Serial.println("SD open fail");
    //return;    
 // }

  while(fh.available())
  {
    Serial.write(fh.read());
  }

  fh.close();
}

This is passive FTP client only. Does the FTP server use passive mode? Does my FTP client code work for you?
http://playground.arduino.cc/Code/FTP

Check your firewall on the FTP server. It may be blocking the data port.

edit: I checked this FTP code on a Mega2560, and the memory usage was very close to the max SRAM available on an Uno in its vanilla state. Add some strings and veriables, and it will be out of SRAM.

oh really, bugger, I ran the vanilla code as it was and it worked straight away, it dropped the file off perfectly, but as I stated I needed it to work with sdfat that was my really only change to the build.

but I have a few more things going on with my build if the SRAM is going to be an issues is there anything else I can try to get the files off the unit that will not take much SRAM?

I'm not sure what you can do. You are on the ragged edge of running out of SRAM. I use this to upload and download files, not as part of another sketch. Best advice I can give is obtain a Mega2560.

I think this may have something to do with my issue with it,

#ifdef FTPWRITE
  ifstream sdin(fileName);
  if (!sdin.is_open()) error("open");
  Serial.print("File is Open");
  Serial.print(fileName);

it has lost the reference to fh even thou I have declared it at the start as
SdFile fh; unless that is incorrect.

#ifdef FTPWRITE
  fh = SD.open(fileName,FILE_READ);

I am running it up on a mega 2650 r3 so I should be okay at least for the testing part.

If you have a Mega2560, you aren't even close to running out of SRAM with my sketch.

yer then it must be my code if I just try and convert the code to use it with sdfat this is what I am getting as an error

FTP_Upload.ino:282:27: error: invalid suffix "_READ" on integer constant
FTP_Upload.ino: In function 'byte doFTP()':
FTP_Upload:81: error: no match for 'operator=' in 'fh = file.SdFile::.SdBaseFile::open(((const char*)((char*)(& fileName))), 1u)'
C:\arduino-1.0.3\libraries\SdFat/SdFile.h:32: note: candidates are: SdFile& SdFile::operator=(const SdFile&)
FTP_Upload:87: error: no match for 'operator!' in '!fh'
FTP_Upload.ino:87: note: candidates are: operator!(bool)
FTP_Upload.ino: In function 'void readSD()':
FTP_Upload:284: error: no match for 'operator!' in '!fh'
FTP_Upload.ino:284: note: candidates are: operator!(bool)

I have only really added the

#include <SdFat.h>
#include <SdFatUtil.h>
#define error(s) sd.errorHalt_P(PSTR(s))

SdFat sd;
SdFile fh;
SdFile file;


const uint8_t chipSelect = SS;

and removed the File = fh

/*
   FTP passive client for IDE v1.0.1 and w5100/w5200
   Posted October 2012 by SurferTim
*/
#include <SdFat.h>
#include <SdFatUtil.h>
#include <Ethernet.h>
#include <SPI.h>
// comment out next line to write to SD from FTP server
#define FTPWRITE

#define error(s) sd.errorHalt_P(PSTR(s))

SdFat sd;
SdFile fh;
SdFile file;


const uint8_t chipSelect = SS;

// this must be unique
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x59, 0x67 };  
char serverName[] = "update.fpt.com";

// change to your network settings
IPAddress ip( 192, 168, 3, 177 );    
IPAddress gateway( 192, 168, 3, 254 );
IPAddress subnet( 255, 255, 255, 0 );

// change to your server
//IPAddress server(serverName);

EthernetClient client;
EthernetClient dclient;

char outBuf[128];
char outCount;

// change fileName to your file (8.3 format!)
char fileName[13] = "10001602.TXT";

void setup()
{
  Serial.begin(9600);

  pinMode(10,OUTPUT);
  digitalWrite(10,HIGH);

 if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt();

  Ethernet.begin(mac, ip, gateway, gateway, subnet); 
  digitalWrite(10,HIGH);
  delay(2000);
  Serial.println("Ready. Press f or r");
}

void loop()
{
  byte inChar;

  inChar = Serial.read();

  if(inChar == 'f')
  {
    if(doFTP()) Serial.println("FTP OK");
    else Serial.println("FTP FAIL");
  }

  if(inChar == 'r')
  {
    readSD();    
  }

}



byte doFTP()
{
#ifdef FTPWRITE
fh = file.open(fileName, O_READ);
#else
  SD.remove(fileName);
  fh = file.open(fileName,FILE_WRITE);
#endif

  if(!fh)
  {
    Serial.println("SD open fail");
    return 0;    
  }

#ifndef FTPWRITE  
  if(!fh.seek(0))
  {
    Serial.println("Rewind fail");
    fh.close();
    return 0;    
  }
#endif

  Serial.println("SD opened");

  if (client.connect(serverName,21)) {
    Serial.println("Command connected");
  } 
  else {
    fh.close();
    Serial.println("Command connection failed");
    return 0;
  }

  if(!eRcv()) return 0;

  client.write("USER test\r\n");

  if(!eRcv()) return 0;

  client.write("PASS pas!\r\n");

  if(!eRcv()) return 0;

  client.write("SYST\r\n");

  if(!eRcv()) return 0;

  client.write("PASV\r\n");

  if(!eRcv()) return 0;

  char *tStr = strtok(outBuf,"(,");
  int array_pasv[6];
  for ( int i = 0; i < 6; i++) {
    tStr = strtok(NULL,"(,");
    array_pasv[i] = atoi(tStr);
    if(tStr == NULL)
    {
      Serial.println("Bad PASV Answer");    

    }
  }

  unsigned int hiPort,loPort;

  hiPort = array_pasv[4] << 8;
  loPort = array_pasv[5] & 255;

  Serial.print("Data port: ");
  hiPort = hiPort | loPort;
  Serial.println(hiPort);

  if (dclient.connect(serverName,hiPort)) {
    Serial.println("Data connected");
  } 
  else {
    Serial.println("Data connection failed");
    client.stop();
    fh.close();
    return 0;
  }

#ifdef FTPWRITE 
  client.write("STOR ");
  client.println(fileName);
#else
  client.write("RETR ");
  client.println(fileName);
#endif

  if(!eRcv())
  {
    dclient.stop();
    return 0;
  }

#ifdef FTPWRITE
  Serial.println("Writing");

  byte clientBuf[64];
  int clientCount = 0;

  while(fh.available())
  {
    clientBuf[clientCount] = fh.read();
    clientCount++;

    if(clientCount > 63)
    {
      Serial.println("Packet");
      dclient.write(clientBuf,64);
      clientCount = 0;
    }
  }

  if(clientCount > 0) dclient.write(clientBuf,clientCount);

#else
  while(dclient.connected())
  {
    while(dclient.available())
    {
      char c = dclient.read();
      fh.write(c);      
      Serial.write(c); 
    }
  }
#endif

  dclient.stop();
  Serial.println("Data disconnected");

  if(!eRcv()) return 0;

  client.write("QUIT\r\n");

  if(!eRcv()) return 0;

  client.stop();
  Serial.println("Command disconnected");

  fh.close();
  Serial.println("SD closed");
  return 1;
}
//************************************ errors**************
byte eRcv()
{
  byte respCode;
  byte thisByte;

  while(!client.available()) delay(1);

  respCode = client.peek();

  outCount = 0;

  while(client.available())
  {  
    thisByte = client.read();    
    Serial.write(thisByte);

    if(outCount < 127)
    {
      outBuf[outCount] = thisByte;
      outCount++;      
      outBuf[outCount] = 0;
    }
  }

  if(respCode >= '4')
  {
    efail();
    return 0;  
  }

  return 1;
}


void efail()
{
  byte thisByte = 0;

  client.write("QUIT\r\n");

  while(!client.available()) delay(1);

  while(client.available())
  {  
    thisByte = client.read();    
    Serial.write(thisByte);
  }

  client.stop();
  Serial.println("Command disconnected");
  fh.close();
  Serial.println("SD closed");
}

void readSD()
{
  fh = file.open(fileName,0_READ);

  if(!fh)
  {
    Serial.println("SD open fail");
    return;    
  }

  while(fh.available())
  {
    Serial.write(fh.read());
  }

  fh.close();
}

Have you got any ideas how I have can adjust the code to work ?

Onenate:
FTP_Upload.ino:282:27: error: invalid suffix "_READ" on integer constant

I think this line has a typo in it:

	fh = file.open(fileName,0_READ);

Hint: it is not legal for variable names to start with a decimal digit.

well i can't see what has changed but I copied your line I get this error now
110:28: error: invalid suffix "_READ" on integer constant

/*
 * Append a line to a file - demo of pathnames and streams
 */
#include <SdFat.h>
#include <SdFatUtil.h>
#include <Ethernet.h>
#include <SPI.h>


#define FTPWRITE

// this must be unique
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x59, 0x67 };  
// FTP Server name
char serverName[] = "update.ftp.com.au";
//FTP Stuff
EthernetClient client;
EthernetClient dclient;
char outBuf[128];
char outCount;
char fileName[13] = "10001602.TXT";

// FTP Wait time
int FTPWait[1];

// change to your network settings
IPAddress ip( 192, 168, 3, 177 );    
IPAddress gateway( 192, 168, 3, 254 );
IPAddress subnet( 255, 255, 255, 0 );

// SD chip select pin
const uint8_t chipSelect = SS;

// file system object
SdFat sd;
SdFile fh;
SdFile file;

// define a serial output stream
ArduinoOutStream cout(Serial);
//------------------------------------------------------------------------------
/*
 * Append a line to LOGFILE.TXT
 */
void logEvent(const char *msg) {
  
  // create or open a file for append
  ofstream sdlog("10001602.TXT", ios::out | ios::app);

  // append a line to the file
  sdlog << msg << endl;

  // check for errors
  if (!sdlog) sd.errorHalt("append failed");

  sdlog.close();
}
//------------------------------------------------------------------------------
void setup() {
  Serial.begin(9600);

  if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt();

  // append a line to the logfile
  logEvent("Sytem Started");

 }
//------------------------------------------------------------------------------
void loop() {
  // pstr stores strings in flash to save RAM
  cout << pstr("Type any character to start\n");
//  if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt();

  // append a line to the logfile
  logEvent("Another line for the logfile");

  cout << "Done - check on the SD" << endl;
  
if (FTPWait[0] == 10)
{     
Serial.print("Start FTP Upload");

  if(doFTP()) Serial.println("FTP OK");
    else Serial.println("FTP FAIL");
 
 
 FTPWait[0] = FTPWait[0] = 0;// resset FTP count
} 
  
FTPWait[0] = FTPWait[0] + 1 ;  


Serial.print(FTPWait[0]);


   
     delay(1000);  
}


//************************** FTP ********************

byte doFTP()
{
#ifdef FTPWRITE
  fh = file.open(fileName, 0_READ);
#else
  sd.remove(fileName);
#endif


#ifndef FTPWRITE  
  if(!fh.seek(0))
  {
    Serial.println("Rewind fail");
    fh.close();
    return 0;    
  }
#endif

  Serial.println("SD opened");

  if (client.connect(serverName,21)) {
    Serial.println("Command connected");
  } 
  else {
    fh.close();
    Serial.println("Command connection failed");
    return 0;
  }

  if(!eRcv()) return 0;

  client.write("USER username\r\n");

  if(!eRcv()) return 0;

  client.write("PASS pasword\r\n");

  if(!eRcv()) return 0;

  client.write("SYST\r\n");

  if(!eRcv()) return 0;

  client.write("PASV\r\n");

  if(!eRcv()) return 0;

  char *tStr = strtok(outBuf,"(,");
  int array_pasv[6];
  for ( int i = 0; i < 6; i++) {
    tStr = strtok(NULL,"(,");
    array_pasv[i] = atoi(tStr);
    if(tStr == NULL)
    {
      Serial.println("Bad PASV Answer");    

    }
  }

  unsigned int hiPort,loPort;

  hiPort = array_pasv[4] << 8;
  loPort = array_pasv[5] & 255;

  Serial.print("Data port: ");
  hiPort = hiPort | loPort;
  Serial.println(hiPort);

  if (dclient.connect(serverName,hiPort)) {
    Serial.println("Data connected");
  } 
  else {
    Serial.println("Data connection failed");
    client.stop();
    fh.close();
    return 0;
  }

#ifdef FTPWRITE 
  client.write("STOR ");
  client.println(fileName);
#else
  client.write("RETR ");
  client.println(fileName);
#endif

  if(!eRcv())
  {
    dclient.stop();
    return 0;
  }

#ifdef FTPWRITE
  Serial.println("Writing");

  byte clientBuf[64];
  int clientCount = 0;

  while(fh.available())
  {
    clientBuf[clientCount] = fh.read();
    clientCount++;

    if(clientCount > 63)
    {
      Serial.println("Packet");
      dclient.write(clientBuf,64);
      clientCount = 0;
    }
  }

  if(clientCount > 0) dclient.write(clientBuf,clientCount);

#else
  while(dclient.connected())
  {
    while(dclient.available())
    {
      char c = dclient.read();
      fh.write(c);      
      Serial.write(c); 
    }
  }
#endif

  dclient.stop();
  Serial.println("Data disconnected");

  if(!eRcv()) return 0;

  client.write("QUIT\r\n");

  if(!eRcv()) return 0;

  client.stop();
  Serial.println("Command disconnected");

  fh.close();
  Serial.println("SD closed");
  return 1;
}

byte eRcv()
{
  byte respCode;
  byte thisByte;

  while(!client.available()) delay(1);

  respCode = client.peek();

  outCount = 0;

  while(client.available())
  {  
    thisByte = client.read();    
    Serial.write(thisByte);

    if(outCount < 127)
    {
      outBuf[outCount] = thisByte;
      outCount++;      
      outBuf[outCount] = 0;
    }
  }

  if(respCode >= '4')
  {
    efail();
    return 0;  
  }

  return 1;
}


void efail()
{
  byte thisByte = 0;

  client.write("QUIT\r\n");

  while(!client.available()) delay(1);

  while(client.available())
  {  
    thisByte = client.read();    
    Serial.write(thisByte);
  }

  client.stop();
  Serial.println("Command disconnected");
  fh.close();
  Serial.println("SD closed");
}

void readSD()
{
 ifstream sdin(fileName);
  if (!sdin.is_open());

  //if(!fh) // error need to look at
  //{
   // Serial.println("SD open fail");
    //return;    
 // }

  while(fh.available())
  {
    Serial.write(fh.read());
  }

  fh.close();
}

Also in regards to

Hint: it is not legal for variable names to start with a decimal digit.

are you refereeing to the file name as I have tried to upload this file with standard code an it work straight away.

I am not too sure why I am finding it so hard to convert the code from sd to sdfat as most of the variable should stay the same

Sorry, I am confused by all those #ifdefs and I may have got your code wrong, but if you are using the SD library I think you should

open("file.txt", FILE_READ);

It still looks like you are trying to open the file using zero_READ, rather than Oh_READ.

Looking for alternatives, is the destination server under your control (i.e., you can install whatever software you like, you have no special security concerns...)? Is the file binary or text? Is it like a log file, that you can append to an existing file?

It just a standard log.txt file with text staying at the moment "Another line for the logfile"

Paul is the zero meant to be an "o" not a zero?

if I change the zero I get a

invalid suffix "_READ" on integer constant

if I change it to and "o"

FTP_Upload:282: error: no match for 'operator=' in 'fh = file.SdFile::.SdBaseFile::open(((const char*)((char*)(& fileName))), 1u)'

byte doFTP()
{
#ifdef FTPWRITE
  fh = file.open(fileName, O_READ);
#else
  SD.remove(fileName);
  fh = SD.open(fileName,FILE_WRITE);
#endif