Arduino reading from Ftp server problem

Hi, I'm trying to read some .txt files stored in my ftp server with my arduino uno, using the ethernet shield, micro SD and using this code as a base Arduino Playground - FTP. The idea is that my arduino read the first character in the txt file and do something, and if I update the txt file with a new character, the arduino has to read it again and do other stuff. My problem is, that the arduino just read one time, and then, when I update the txt (whith the same name), the arduino doesn't do the instrucction of the new character, it doesn't read the updated txt :(.
I thought that is happening because the code is writing only for try to connect with the ftp server when the user press f, but the serial monitor just left me press f when I close and open it again. I tried to erase that part in the loop and just leave doFTP(), but the arduino continue doing the same thing. It just read the txt when I connect the arduino, I close the serial monitor and open again, or compile the code again.
I don't know if this topic goes here, but i will be very greatfull if you could help me :slight_smile:
Thx and I'll be waiting for your answer

PS: Sorry for my bad English xD

Have you tried reading the file with a web browser to insure the text file was actually changed? There is no cache function in my FTP code, so it must read the file again.

Yes, the txt file is actually updated. I verified this with a web browser and other client :frowning:

Did you remove or alter the code that rewinds the file pointer on the Arduino code? This part of the code rewinds the file pointer so the code writes to the start of the file. Otherwise it appends the new read to the end of the current file contents.

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

I didn't alter or remove that part of the code, but I'm afraid that I didn't understand your point. Are you telling me that the code in every loop doesn't read from the beginning of the txt file? I don't understand the part of the code writing...I just want to read the firs character, not write anywhere.

Thanks for the answers :slight_smile:

If you are reading from the SD card (opened for read), the file pointer is reset to the beginning of the file.

If you open the SD card file for writing, the file pointer is set to the end of the file, and any new data is written to the end of the current contents (appended). You must call fh.seek(0) to rewind the file pointer to the start of the file so the new read will overwrite the current contents.

Are you certain the new read from the FTP server is not being written to the end of the SD card file?

The fact is that I'm just reading the characters in the txt file in the ftp server with que fuction dclient.read(), so I actually never write in the SD card... In the beginning I tried to do this (create a copy of the file in my SD card and then read it) but I couldn't, I don't know why, but I didn't continue trying because I realize that the character needed could be obtained with char c=dclient.read().
This part of the code is

#else
  while(dclient.connected())
  {
    while(dclient.available())
    {
      char c =dclient.read();

So my first impression is that maybe in the loops I'm not entering in the previous whiles, but I don't understand why...

Post your code.

Here it is

/*
   FTP passive client for IDE v1.0.1 and w5100/w5200
   Posted October 2012 by SurferTim
*/

#include <SD.h>
#include <SPI.h>
#include <Ethernet.h>
// comment out next line to write to SD from FTP server
//#define FTPWRITE

// change to your network settings
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x59, 0x67 };  
int pin=7;
String h;

// change to your network settings
IPAddress ip( 192, 168, 1, 117 );    
IPAddress gateway( 192, 168, 1, 1 );
IPAddress subnet( 255, 255, 255, 0 );

// change to your server
char server[]="www.acertec.cl";

EthernetClient client;
EthernetClient dclient;

char outBuf[128];
char outCount;

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

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

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

  if(SD.begin(4) == 0)
  {
    Serial.println(F("SD init fail"));          
  }

  Ethernet.begin(mac, ip, gateway, gateway, subnet); 
  digitalWrite(10,HIGH);
  delay(2000);
}
File fh;
void loop()
{
  doFTP();
  delay(1000);
  fh.seek(0);

}


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

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

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

  Serial.println(F("SD opened"));

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

  if(!eRcv()) return 0;

  client.println(F("USER SECRET"));

  if(!eRcv()) return 0;

  client.println(F("PASS SECRET"));

  if(!eRcv()) return 0;

  client.println(F("SYST"));

  if(!eRcv()) return 0;

  client.println(F("PASV"));

  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"));    

    }
  }

  unsigned int hiPort,loPort;

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

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

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

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

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

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

  byte clientBuf[64];
  int clientCount = 0;

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

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

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

#else
  while(dclient.connected())
  {
    while(dclient.available())
    {
      char c =dclient.read();
      h=String(c);
      fh.write(c);      
      Serial.write(c); 
      if (h=="s")
      {
        digitalWrite(pin,HIGH);
       }
       else if(h=="n")
       {
         digitalWrite(pin,LOW);
        }
    }
  }
#endif

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

  if(!eRcv()) return 0;

  client.println(F("QUIT"));

  if(!eRcv()) return 0;

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

  fh.close();
  Serial.println(F("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.println(F("QUIT"));

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

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

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

void readSD()
{
  fh = SD.open(fileName,FILE_READ);

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

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

  fh.close();
}

As I said in the first post, is the same code that it is in the playground of arduino with the change in the dclient.read() part. I know that I'm not using all the code, but i was scared of erase sth and ruin all the code, plus I'm a little messy xD
I really think that is a problem with client stuffs, but don't know what D:

That looks ok, but what is in the led.txt file on the FTP server?

edit: I would have used this.

      char c =dclient.read();
      fh.write(c);      
      Serial.write(c); 
      if (c=='s')
      {
        digitalWrite(pin,HIGH);
       }
       else if(c=='n')
       {
         digitalWrite(pin,LOW);
        }

Hi again. In led.txt is a character, s or n.
I tried to add a count variable in the loop to see if the arduino is acctually doing the loop and doing doFTP() fuction that connect to the FTP server. I printed this variable in the serial monitor and the value has just appeared once, so I think that is the problem. Some function or sth in the code is stopping the loop :frowning:

I solve my problem commenting this line in the code

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

  //if(!eRcv()) return 0; <--------------------------THIS LINE

  client.println(F("QUIT"));

  if(!eRcv()) return 0;

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

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

I don't know why this solve my problem, but it does xD
Thanks for all your help ;)!!