FTP-Client library Needed

Hi there

We are working on a project that requires transferring files between an Arduino Ethernet Shield and an FTP server.
We have 3 Ardunio Mega microcontrollers each with an Ethernet Shield and a microSD card. We bought a product called Web server in a Box that has a PIC microcontroller that supports HTTP and FTP. We thought of creating a web page so we can upload files easily from any device but that won't work because the server doesn't support PHP. FTP seems to be easier so we installed an FTP server on Linux for the purpose of testing and setting up the Arduino.

The problem we're facing now is that there is no FTP-client library for Arduino. We looked up the internet and found nothing. We thought about writing our own library which would contain the main commands like "ls", "cd", "get", "delete", ... etc. but that would take a long time and there are many things to consider.

Our hope is that we find a library or a way to use the Arduino as an FTP-client that checks a directory on the FTP server for new files, lists files and downloads certain files into its microSD card. Again, the microSD is on the Ethernet Shield and we'll be using Ethernet to connect to through a router to the FTP server.

Any help would be appreciated.

I don't think there is a FTP example or library yet. I have started a FTP client program. Maybe that will help.

SurferTim,

Thanks a lot buddy. I was reading your post on another thread and found your sketch. So I copied it and came back here to post it and let people know that I'll be trying it to find that you've already replied to my post. :fearful: XD

This is the code written by SurferTim that I'll be testing:

// w5100 FTP passive client
// IDE v1.0 only

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

// Set to your network settings
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x59, 0x67 };  
IPAddress ip( 192, 168, 0, 2 );    
IPAddress gateway( 192, 168, 0, 1 );
IPAddress subnet( 255, 255, 255, 0 );

// Change this to the ip of the ftp server
IPAddress server( 192, 168, 0, 3 );

EthernetClient client;
EthernetClient dclient;

char outBuf[128];
char outCount;

void setup()
{
  Serial.begin(9600);
  pinMode(4,OUTPUT);
  digitalWrite(4,HIGH);
  Ethernet.begin(mac, ip, gateway, gateway, subnet); 
  delay(2000);
  Serial.println("Ready. Press f");
}

void loop()
{
  byte inChar;

  inChar = Serial.read();

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

byte sendFTP()
{
  if (client.connect(server,21)) {
    Serial.println("Command connected");
  } 
  else {
    Serial.println("Connamd connection failed");
    return 0;
  }

  if(!eRcv()) return 0;

// Change to your user and password  
  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 rtnVal[32];
  
  sscanf(outBuf,"%*s %*s %*s %*s %s",rtnVal);

  unsigned int hiPort,loPort;

  sscanf(rtnVal,"%*c%*d%*c%*d%*c%*d%*c%*d%*c%d%*c%d",&hiPort,&loPort);
  
  Serial.print("Port ");
  hiPort = hiPort << 8;
  loPort = loPort & 255;
  hiPort = hiPort | loPort;
  Serial.println(hiPort);
  

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

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

  if(!eRcv()) return 0;

  dclient.stop();
  client.stop();
  Serial.println("disconnected");
  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();
  dclient.stop();
  Serial.println("disconnected");
}

I'll let you know how it works.

If someone else has got another idea, please let me know.

For an Anonymous FTP mode should I use the following username and password?
client.write("USER\r\n");
client.write("PASS\r\n");

I tried your program. I keep getting this no matter what I put as a username and password:

Ready. Press f << I press f here
Command connection failed
FTP failed

I've also tried playing with the server configuration. It could be a firewall issue since I'm using the dorm network but I doubt it because I tried an example (ChatServer example) and it worked just fine.

I'm using vsftpd and here is my configuration file:

I tried commenting out "anonymous_enable=YES" then tried using null username and pass but it didn't work so I tried using my unix username and pass and it didn't work either.

from the output message, it seems to be failing the conditions of these two if statements:

  if(inChar == 'f')
  
  {
    if(sendFTP()) // then failing this
         Serial.println("FTP OK");
    else Serial.println("FTP failed");   
  }
}

byte sendFTP()
{
  if (client.connect(server,21)) { //failing this first
    Serial.println("Command connected");
  } 
  else { 
    Serial.println("Command connection failed");
    return 0;
  }

Any ideas?

AFAIK (and IIRC) the login name for anon FTP is "anonymous" and the password is normally your host name - try "wherever.com" :).

I tried using my unix username and pass

You should never use that password on any other machine, not even as a test. The other end could be logging that info.

Pete

Thanks for the info el_supremo

Yeah I found that anonymous is the username .. but when not in anonymous FTP I should use existing UNIX account details (usernames, passwords) right? At least that's what I read.
You're right about not using it on another machine. I guess I can make another limited unix account to test this instead of using my main unix account details.

but when not in anonymous FTP I should use existing UNIX account details

You should use whatever username/password has been set up for that machine. If you're logging into your own FTP server, set up a username and password for it and use those.

Pete