FTP

Bonjour à tous,

J'utilise avec succès l'exemple suivant : Arduino Playground - FTP

J'ai néanmoins 2 besoins complémentaires:

  • pouvoir dowloader & télécharger des fichiers dans la même connexion FTP. Aujourd'hui je me débrouille en faisant 2 fois le process de connexion/déconnexion. Ca fonctionne, mais je ne trouve pas ça optimum du tout ...

  • Je souhaite également pouvoir supprimer un fichier sur le serveur distant (s'il existe sur ma carte SD)

Merci pour toute votre aide.

Fabrice.

Bonjour,

Pas la peine de m’envoyer un MP pour que je vienne voir un topic …

  1. Suffit d’enchainer les commandes dans le bon ordres une fois que tu as un canal de connexion pour les données.
    Prend la fonction doFTP() et fait en une copie.
    Ensuite tu peut faire à la main ce que fait de base le #define FTPWRITE pour avoir une version qui upload et une version qui download.

  2. Voir la commande “DELE” pour supprimer un fichier distant.
    http://en.wikipedia.org/wiki/List_of_FTP_commands

Merci pour ton aide! Je vais tester ...

OK désolé (en plus t'en a peut être eu 2)

brakc:
Merci pour ton aide! Je vais tester ...

Quand tu auras tes deux fonctions tu remarqueras qu'une partie (la connexion) est identique pour les deux.
Si tu veut pousser le truc un peu plus loin tu pourras faire une fonction séparé pour la connexion et la déconnexion :wink:

brakc:
OK désolé (en plus t'en a peut être eu 2)

C'est pas grave.

Oui 2 fonctions ça serait le top, mais pour l’instant je bloque sur la déconnexion je crois …

Ca fonctionne bien, j’ai bien téléchargé mon fichier puis downloadé l’autre, mais mon programme ne boucle pas…

Il affiche mon msg “SD opened for dowload” et basta. une idée stp?

void loop()
{

if(doFTP()) Serial.println(F(“FTP OK”));
else Serial.println(F(“FTP FAIL”));

}

File fh;

byte doFTP()
{

//Ouverture FTP -------------------------------------------------------------------------------------
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 xxxxx”));

if(!eRcv()) return 0;

client.println(F(“PASS xxxxxxx”));

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 = 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;*

  • }*

  • //Fin ouverture FTP -----------------------------------------------------------------------------------*

  • //Téléchargement -------------------------------------------------------------------------------------*

  • fh = SD.open(fileName,FILE_READ);*

  • client.print(F("STOR "));*

  • client.println(repFTPinput+fileName);*

  • if(!fh)*

  • {*

  • Serial.println(F(“SD open fail”));*

  • return 0; *

  • }*

  • if(!fh.seek(0))*

  • {*

  • Serial.println(F(“Rewind fail”));*

  • fh.close();*

  • return 0; *

  • }*

  • Serial.println(F(“SD opened”));*

  • if(!eRcv())*

  • {*

  • dclient.stop();*

  • return 0;*

  • }*

  • Serial.println(F(“Writing upload”));*

  • 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);*

  • // Fin téléchargement -------------------------------------------------------------------------------------*

  • // Download -------------------------------------------------------------------------------------*

  • SD.remove(fileNameInit);*

  • fh = SD.open(fileNameInit,FILE_WRITE);*

  • if(!fh)*

  • {*

  • Serial.println(F(“SD open fail”));*

  • return 0; *

  • }*

  • Serial.println(F(“SD opened for dowload”));*

  • client.print(F("RETR "));*

  • client.println(repFTPoutput+fileNameInit);*

_ // Ca bloque ici !!!_

  • if(!eRcv())*
  • {*
  • dclient.stop();*
  • return 0;*
  • }*
  • while(dclient.connected())*
  • {*
  • while(dclient.available())*
  • {*
  • char c = dclient.read();*
  • fh.write(c); *
  • Serial.write(c);*
  • }*
  • }*
  • // Fin download -------------------------------------------------------------------------------------*
  • // Cloture FTP -------------------------------------------------------------------------------------*
  • 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;*
    }
  • // Fin cloture FTP -------------------------------------------------------------------------------------*
    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”));*
    }

brakc:
Oui 2 fonctions ça serait le top, mais pour l'instant je bloque sur la déconnexion je crois ...

Ca fonctionne bien, j'ai bien téléchargé mon fichier puis downloadé l'autre, mais mon programme ne boucle pas...

Il affiche mon msg "SD opened for dowload" et basta. une idée stp?

Bonjour
je ne suis pas un expert reseau, mais le probleme ne viendrait il pas de cette limitation ? :

The library supports up to four concurrent connection (incoming or outgoing or a combination).

Met ton code entre balise code (#) parce que là c'est illisible :wink:

skywodd:
Met ton code entre balise code (#) parce que là c’est illisible :wink:

OK Skywodd!

Bon, ça va mieux. Mais ça fonctionne pas encore comme je le voudrais …

J’ai fait 4 fonctions:
FTPopen()
FTPupload()
FTPdownload()
FTPclose()

J’ai maintenant 2 soucis:

  • lorsque je lance un FTPupload() et un FTPdownload() à la suite, la fonction FTPdownload() bloque au sur mon msg “SD opened for download”. Je pense qu’il doit manquer quelque chose dans l’échange de connexion avant de lancer la 2d fonction. Si je lance juste un FTPupload() ou un FTPdownload() ça passe sans souci!

  • autre point, lorsque je coupe mon port Série (la fonction FTPclose() ne se fait pas ou en partie). Au prochain lancement du port Série j’ai donc des pb de connexion. J’ai donc fait ce petite test qui n’est à mon sens pas propre. Aurais-tu une autre idée stp?

  if(FTPopen() == 0) {
  FTPopen();
  }

Globalement, je pense que je ne maitrise pas l’ensemble des contrôles d’erreurs…

Je te remercie pour ton aide.

File fh;

void loop()
{
  if(FTPopen() == 0) { // Download file on SD
  FTPopen();
  }

  FTPupload("test.txt");
  FTPdownload("BOX_0001.ini");
  
  FTPclose(); // Close FTP Server
}



byte FTPopen()
{

  Serial.println(F(" "));
  Serial.println(F(" "));
  Serial.println(F("Connection FTP -----------------"));

  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 xxxxxx"));
  if(!eRcv()) return 0;
  client.println(F("PASS xxxxx"));
  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;
  }
  delay(200);

}


byte FTPupload(char fileName[13])
{

	Serial.println(F("Upload -------------------------"));

	fh = SD.open(fileName,FILE_READ);

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

	Serial.println(F("SD opened for upload"));
	client.print(F("STOR "));
	client.println(repFTPinput+fileName);

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

	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);
	Serial.println(F("File uploaded"));
  	
  	delay(200);
        return 1;

}



byte FTPdownload(char fileNameInit[13])
{
	Serial.println(F("Download -----------------------"));

	SD.remove(fileNameInit);
	fh = SD.open(fileNameInit,FILE_WRITE);

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

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

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

	client.print(F("RETR "));
	client.println(repFTPoutput+fileNameInit);

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

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


  	delay(200);
	return 1;
}




byte FTPdelete(char fileNameInit[13])
{
	Serial.println(F("Delete -----------------------"));

	client.print(F("DELE "));
	client.println(repFTPoutput+fileNameInit);
	Serial.println(F("File deleted"));
	
	delay(200);
}



byte FTPclose()
{
  Serial.println(F("Close FTP -----------------------"));

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

  Serial.println(F("--------------------------------"));

}



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"));
}
  1. Donne ton code COMPLET, pas juste un morceau :wink:
  2. Fait un coup de CTRL+T pour mettre en forme ton code.
  3. C'est bizarre ça :
client.println(repFTPinput+fileName);

Essaye un truc dans ce genre :

client.print(repFTPinput);
client.println(fileName);

skywodd:

  1. Donne ton code COMPLET, pas juste un morceau :wink:
  2. Fait un coup de CTRL+T pour mettre en forme ton code.
  3. C’est bizarre ça :
client.println(repFTPinput+fileName);

Essaye un truc dans ce genre :

client.print(repFTPinput);

client.println(fileName);

C’est parceque je concatène le path et le nom de fichier en fait …
pi, pour l’instant la fonction FTPdelete() n’est pas utilisée, mais elle fonctionne bien.

Voici le code au complet

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

// this must be unique
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xFE, 0xBA };  

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

// change to your server
IPAddress server( xx, xx, xx, xx );

EthernetClient client;
EthernetClient dclient;

char outBuf[128];
char outCount;

String repFTPinput = "aqua_box/input/BOX_0001/input/"; // download directory
String repFTPoutput = "aqua_box/input/BOX_0001/output/"; // upload directory

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

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

  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()
{


  if(FTPopen() == 0) { // Open FTP server
    FTPopen();
  }


  FTPupload("test.txt"); // Download file on SD
  FTPdownload("BOX_0001.ini"); // Upload file on FTP
  FTPclose(); // Close FTP Server

}


byte FTPopen()
{

  Serial.println(F(" "));
  Serial.println(F(" "));
  Serial.println(F("Connection FTP -----------------"));

  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 XXXXX"));
  if(!eRcv()) return 0;
  client.println(F("PASS XXXXX"));
  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;
  }
  delay(200);

}




byte FTPupload(char fileName[13])
{

  Serial.println(F("Upload -------------------------"));

  fh = SD.open(fileName,FILE_READ);

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

  Serial.println(F("SD opened for upload"));
  client.print(F("STOR "));
  client.println(repFTPinput+fileName);

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

  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);
  Serial.println(F("File uploaded"));

  delay(200);
  return 1;
}



byte FTPdownload(char fileNameInit[13])
{
  Serial.println(F("Download -----------------------"));

  SD.remove(fileNameInit);
  fh = SD.open(fileNameInit,FILE_WRITE);

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

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

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

  client.print(F("RETR "));
  client.println(repFTPoutput+fileNameInit);

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

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

  delay(200);
  return 1;
}




byte FTPdelete(char fileNameInit[13])
{
	Serial.println(F("Delete -----------------------"));

	client.print(F("DELE "));
	client.println(repFTPoutput+fileNameInit);
	Serial.println(F("File deleted"));
	
	delay(200);
}




byte FTPclose()
{
  Serial.println(F("Close FTP -----------------------"));

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

  Serial.println(F("--------------------------------"));

}




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

T’as eu un gros coup de chance, si tu n’avais pas utilisé de String ça aurait pas marché.

Tu peut faire un truc plus simple :

client.print(F("aqua_box/input/BOX_0001/input/"));
client.print(fileName);

skywodd:
T'as eu un gros coup de chance, si tu n'avais pas utilisé de String ça aurait pas marché.

Tu peut faire un truc plus simple :

client.print(F("aqua_box/input/BOX_0001/input/"));

client.print(fileName);

Effectivement, c'est vrai!

Par contre, pour mon FTP je suis un peu perdu là. J'y suis depuis ce matin, je n'arrive pas à le faire tourner correctement grrr

brakc:
…Par contre, pour mon FTP je suis un peu perdu là. J’y suis depuis ce matin, je n’arrive pas à le faire tourner correctement grrr

bonsoir
sans vouloir etre “insistant” , tu a bien vérifié (levée de doutes) que la lib ftp adossée à la lib ethernet n’est pas mise dans les choux avec cette limitation à 4 connections simultanées, comme j’ai exposé au dessus ?

Artouste:

brakc:
...Par contre, pour mon FTP je suis un peu perdu là. J'y suis depuis ce matin, je n'arrive pas à le faire tourner correctement grrr

bonsoir
sans vouloir etre "insistant" , tu a bien vérifié (levée de doutes) que la lib ftp adossée à la lib ethernet n'est pas mise dans les choux avec cette limitation à 4 connections simultanées, comme j'ai exposé au dessus ?

A vrai dire, je ne sais pas trop comment tester ça! Mais ce que je peux dire c'est que ça fonctionne très bien lorsque je fais dans le loop:

  FTPopen();
  FTPupload("test.txt");
  FTPclose();

ou

  FTPopen();
  FTPdownload("BOX_0001.ini");
  FTPclose();

Par contre, avec les 2 fonctions, seule la 1ère fonctionne:

  FTPopen();
  FTPupload("test.txt");
  FTPdownload("BOX_0001.ini");
  FTPclose();

Je pense qu'il y a un paramètre à passer au serveur FTP qui manque afin de pourvoir passer les 2 fonctions à la suite (ou un contrôle d'erreur à faire que je ne fais pas).

Le 2d problème, c'est que lorsque je quitte le serial, la déconnexion ne s'étant pas faite correctement lorsque je relance ça m... :drooling_face:

Ça ne marche pas parce que tu ne gère pas correctement le protocole FTP:
Tu devrais refermer la socket de données après l’upload du fichier et la rouvrir avant le download de l’autre fichier.

cbrandt:
Ça ne marche pas parce que tu ne gère pas correctement le protocole FTP:
Tu devrais refermer la socket de données après l'upload du fichier et la rouvrir avant le download de l'autre fichier.

par un :

dclient.stop();
fh.close();

??

oui, fermer proprement la socket de data (et pour le upload ça indique au serveur que le fichier que tu envoie est complet), mais aussi rouvrir la socket de données à chaque fois: la partie du FTPOpen () qui envoie la command PASV devrait être à la fois au début de FTPUpload () et de FTPDownload ().

  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 = 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;
  }

d’ailleurs du coup la variable dclient pourrait être locale à FTPUpload () et FTPDownload (), de même que outBuf et outCount, mais là c’est du chipotage :slight_smile:

edit: et il manque aussi fh.close () dans FTPUpload () et FTPDownload ()…

cbrandt:
oui, fermer proprement la socket de data (et pour le upload ça indique au serveur que le fichier que tu envoie est complet), mais aussi rouvrir la socket de données à chaque fois: la partie du FTPOpen () qui envoie la command PASV devrait être à la fois au début de FTPUpload () et de FTPDownload ().

Du coup, la fonction FTPopen(), ce n'est que ça, on est d'accord?

byte FTPopen()
{

  Serial.println(F(" "));
  Serial.println(F(" "));
  Serial.println(F("Connection FTP -----------------"));

  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 XXXXX"));
  if(!eRcv()) return 0;
  client.println(F("PASS XXXXX"));
  if(!eRcv()) return 0;
  client.println(F("SYST"));
  if(!eRcv()) return 0;
  
  delay(200);

}

d'ailleurs du coup la variable dclient pourrait être locale à FTPUpload () et FTPDownload (), de même que outBuf et outCount, mais là c'est du chipotage :slight_smile:

edit: et il manque aussi fh.close () dans FTPUpload () et FTPDownload ()…

OK top!

Je teste tout ça se soir :wink:

Du coup, la fonction FTPopen(), ce n'est que ça, on est d'accord?

Oui, tout à fait :slight_smile:
Supprime quand même le fh.close() (dans ftpopen()).
D'ailleurs fh aussi devrait être une variable locale à ftpuload() et ftpdownload().

cbrandt:

Du coup, la fonction FTPopen(), ce n’est que ça, on est d’accord?

Oui, tout à fait :slight_smile:
Supprime quand même le fh.close() (dans ftpopen()).
D’ailleurs fh aussi devrait être une variable locale à ftpuload() et ftpdownload().

Hello, voici ce que ça donne avec les 2 fonctions FTPupload() & FTPdownload() à la suite. La 2d ne passe tirs pas :blush:

Connection FTP -----------------
Command connected
220 FTP Server ready.
331 Password required for xxxxxxxx
230 User xxxxxxxx logged in
215 UNIX Type: L8
 
 
Connection FTP -----------------
Command connection failed
Upload -------------------------
227 Entering Passive Mode (82,165,109,152,225,16).
Data port: 57616
Data connected
SD opened for upload
150 Opening ASCII mode data connection for aqua_box_old/input/BOX_0001/input/test.txt
File uploaded
Download -----------------------
226 Transfer complete
Bad PASV Answer
Bad PASV Answer
Bad PASV Answer
Bad PASV Answer
Bad PASV Answer
Bad PASV Answer
Data port: 0
Data connection failed
Close FTP -----------------------
Data disconnected

Le Serial renvoie le msg “Command connection failed” à cause de mon code suivant:

if(FTPopen() == 0) { // Open FTP server
    FTPopen();
  }

C’est pas jolie, mais c’est pour l’instant le seul moyen que j’ai trouvé pour relancer la fonction FTPopen() après une coupure du Serial (et donc une connexion pas fermée correctement). A voir par la suite pour essayer de faire un truc plus propre …

En revanche, la fonction FTPdownload() ne passe tjrs pas (pi, les 2 fonction passent bien séparément), voici mon code :

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

// this must be unique
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xFE, 0xBA };  

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

// change to your server
IPAddress server( xx, xx, xx, xx );

EthernetClient client;
EthernetClient dclient;

char outBuf[128];
char outCount;

String repFTPinput = "aqua_box_old/input/BOX_0001/input/"; // download directory
String repFTPoutput = "aqua_box_old/input/BOX_0001/output/"; // upload directory

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

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

  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()
{

  if(FTPopen() == 0) { // Open FTP server
    FTPopen();
  }

  //FTPopen();
  FTPupload("test.txt"); // Download file on SD
  FTPdownload("BOX_0001.ini"); // Upload file on FTP
  FTPclose(); // Close FTP Server

}




byte FTPopen()
{

  Serial.println(F(" "));
  Serial.println(F(" "));
  Serial.println(F("Connection FTP -----------------"));

  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 xxxxxxxx"));
  if(!eRcv()) return 0;
  client.println(F("PASS xxxxxxxx"));
  if(!eRcv()) return 0;
  client.println(F("SYST"));
  if(!eRcv()) return 0;

  delay(200);

}




byte FTPupload(char fileName[13])
{

  EthernetClient dclient; //ouverture socket

  Serial.println(F("Upload -------------------------"));

  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;
  }

  fh = SD.open(fileName,FILE_READ);

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

  Serial.println(F("SD opened for upload"));
  client.print(F("STOR "));
  client.println(repFTPinput+fileName);

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

  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);
  Serial.println(F("File uploaded"));

  dclient.stop(); // fermeture socket
  fh.close(); // fermeture fichier
  delay(200);
  return 1;
}




byte FTPdownload(char fileNameInit[13])
{
  Serial.println(F("Download -----------------------"));

  EthernetClient dclient; //ouverture socket

  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;
  }

  SD.remove(fileNameInit);
  fh = SD.open(fileNameInit,FILE_WRITE);

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

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

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

  client.print(F("RETR "));
  client.println(repFTPoutput+fileNameInit);

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

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

  dclient.stop(); // fermeture socket

  fh.close(); //fermeture fichier
  delay(200);
  return 1;
}




byte FTPdelete(char fileNameInit[13])
{

  
	Serial.println(F("Delete -----------------------"));

	client.print(F("DELE "));
	client.println(repFTPoutput+fileNameInit);
	Serial.println(F("File deleted"));
	
	delay(200);
}




byte FTPclose()
{
  Serial.println(F("Close FTP -----------------------"));

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

}




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