Memory fail using SD and ftp comunication

Hi everyone.

I’m trying to create a data logger which sends via ftp the file saved in the SD.
After the first two executions the serial output indicates that the program restarted. The first two executions do the work perfectly but after that the output tries to write “Sto scrivendo su test.tx…” but the serial monitor writes only “St”. I think it’s a memory issue but couldn’t find anything on how to fix this trouble…

#include <SD.h>
#include <SPI.h>
#include <Ethernet.h>
#include <Servo.h>
#include <String.h>


byte mac[] = { 0x90, 0xA2, 0xDA, 0x0E, 0x03, 0x37 };  
IPAddress ip( XXX,XXX,XXX,XXX );    
IPAddress gateway( XXX, XXX, XXX, XXX );
IPAddress subnet( XXX, XXX, XXX, XXX );

IPAddress server( XXX, XXX, XXX, XXX );

EthernetClient client;
EthernetClient dclient;

char outBuf[128];
char outCount;
char ora[2];
char data_ora[] = "LogData 9_7_2014_14_26";


File myfile;
char filename[] = "test.txt";
int switchArray[] = {6,7,8};
boolean lastButton[] = { LOW, LOW, LOW };
boolean currentButton[] = { LOW, LOW, LOW };
boolean repeat = false;

void setup()
{
  Serial.println(FreeRam());
  Serial.begin(9600);
  
  if(SD.begin(4) == 0)
  {
    Serial.println(F("Inizializzazione SD fallita"));
  }
  
  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);
  delay(2000);
  Serial.println(F("Prova FTPlogger"));
  
  for (int i=0; i<3; i++)
  {
    pinMode(switchArray[i], INPUT);
  }
  
  Serial.println(F("Inizializzazione effettuata"));
  myfile = SD.open(filename, FILE_WRITE);
  
  if(myfile)
  {
    if(!repeat)
    {
      Serial.println(F("Scrivo titolo nel file"));
      myfile.println("DATA LOGGER");
      myfile.close();
    }
    
    repeat = true;
  }
  
  else
  {
    Serial.println(F("Errore durante l'apertura del file"));
  }
}


boolean debounce(boolean last, int switchPin)
{
  
  boolean current = digitalRead(switchPin);
  
  if(last != current)
  {
    delay(35);
    current = digitalRead(switchPin);
  }
  
  return current;
}


void loop()
{
  
  for (int i = 0; i<3; i++)
  {
    currentButton[i] = debounce(lastButton[i], switchArray[i]);
    if(lastButton[i] == LOW && currentButton[i] == HIGH)
    {
      myfile = SD.open(filename,FILE_WRITE);
      
      if(myfile)
      {
        Serial.print(F("Sto scrivendo su test.txt..."));
        myfile.print("Pulsante " + String(switchArray[i]));
        myfile.print(" cliccato");
        //manca la parte dell'ora del click
        myfile.close();
        Serial.println(F("Fatto"));
        
        if(ftpbackup())
        {
          Serial.println(F("FTP OK"));
          //freeRam();
        }
        
        else
        {
          Serial.println(F("FTP FAIL"));
        }
          
      }
      
      else
      {
        Serial.println(F("No soi rivat a viergi il file"));
      }
    }
    
    lastButton[i] = currentButton[i];
  }
  
  
}

byte ftpbackup()
{
  myfile = SD.open(filename);
  
  if(!myfile)
  {
    Serial.println(F("Non riesco ad aprire il file nella ftpbackup"));
    return 0;
  }
  
  if (client.connect(server,21))
  {
    Serial.println(F("Command connected"));
  }
  else
  {
    Serial.println(F("Command connection failed"));
    myfile.close();
    return 0;
  }
  
  if (!eRcv()) return 0;
  
  client.write("USER myUserName\r\n");
  
  if (!eRcv()) return 0;
  
  client.write("PASS myPassword\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(F("Bad PASV Answer"));
      client.stop();
      myfile.close(); 
      return 0;  
    }
  }

  unsigned int hiPort,loPort;

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

// end of new code

  Serial.print("Data port: ");
  hiPort = hiPort | loPort;
  Serial.println(hiPort);
  
  if (dclient.connect(server,hiPort)) 
  {
    Serial.println("Data connected");
  } 
  else 
  {
    Serial.println("Data connection failed");
    client.stop();
    myfile.close();
    return 0;
  }
  
  int randNumber = random(0, 60);
  
  itoa(randNumber, ora, 10);
  client.write("MKD ");
  client.write(ora);
  client.write(" \r\n");
  client.write("STOR /");
  client.write(ora);
  client.write("/test.txt\r\n");
  
  if(!eRcv())
  {
    dclient.stop();
    return 0;
  }
  
  Serial.println("Writing");

// This needs improvement

  while(myfile.available())
  {
    char c = myfile.read();
    dclient.write(c);
  }
  
  dclient.stop();
  Serial.println(F("Disconnessione in corso"));
  
  if(!eRcv()) return 0;

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

  if(!eRcv()) return 0;

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

  myfile.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");
  myfile.close();
  Serial.println("SD closed");
}

int freeRam () {
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
  }

Thanks for your support!

Which Arduino device are you using? If an Uno, you are probably running out of SRAM. The variable outBuf should be reduced to 64 bytes instead of 128 bytes, then change the eRcv function to load only 63 characters into it.