Descargar ficheros desde un ESp32 vía ftp

A veces si en nuestro ESP32 o ESP866 vamos almacenando medidas varias en archivos diferentes en una SD conectada a nuestro ESPXX, necesitamos alguna vía de descargar o visualizar esos archivos sin tener desconectar la tarjeta SD , punto donde entra el servicio ftp, el cual nos va a facilitar esta tarea de un modo muy sencillo, como vamos a ver en este post.

El protocolo de transferencia de archivos (en inglés File Transfer Protocol o FTP) es un protocolo de red para la transferencia de archivos entre sistemas conectados a una red TCP (Transmission Control Protocol), basado en la arquitectura cliente-servidor. Desde un equipo cliente se puede conectar a un servidor para descargar archivos desde él o para enviarle archivos, independientemente del sistema operativo utilizado en cada equipo.

El servicio FTP es ofrecido por la capa de aplicación del modelo de capas de red TCP/IP al usuario, utilizando normalmente el puerto de red 20 y el 21. Un problema básico de FTP es que está pensado para ofrecer la máxima velocidad en la conexión, pero no la máxima seguridad, ya que todo el intercambio de información, desde el login y password del usuario en el servidor hasta la transferencia de cualquier archivo, se realiza en texto plano sin ningún tipo de cifrado, con lo que un posible atacante puede capturar este tráfico, acceder al servidor y/o apropiarse de los archivos transferidos.

Para solucionar este problema son de gran utilidad aplicaciones como SCP y SFTP, incluidas en el paquete SSH, que permiten transferir archivos pero cifrando todo el tráfico.

Biblioteca

La biblioteca está disponible directamente desde el Administrador de bibliotecas de Arduino IDE.

O el código fuente de GitHub.

Puede encontrar una biblioteca  aquí .Haga clic en el  botón DESCARGAS  en la esquina superior derecha y cambie el nombre de la carpeta sin comprimir SimpleFTPServer.

Verifique que SimpleFTPServer contenga FtpServer.cpp, FtpServer.h, FtpServerKey.he SimpleFTPServer.h .

Coloque la carpeta de la biblioteca SimpleFTPServer en su carpeta /libraries/.

Es posible que deba crear la subcarpeta de bibliotecas si es su primera biblioteca.

Reinicie el IDE.

Seleccione FS en esp8266

También puede habilitar LittleFS para esp8266 editando la línea en el archivo FtpServerKey.h

1#defineDEFAULT_STORAGE_TYPE_ESP8266 STORAGE_SPIFFS

en

1#defineDEFAULT_STORAGE_TYPE_ESP8266 STORAGE_LITTLEFS

Uso

Aquí hay un ejemplo para esp8266

/*
 *  WeMos D1 mini (esp8266)
 *  Start FTP server to upload data on SPIFFS
 *  by Mischianti Renzo <https://www.mischianti.org>
 *
 *  https://www.mischianti.org/2019/05/11/wemos-d1-mini-esp8266-integrated-spiffs-filesistem-part-2/
 *
 */
 
#include "Arduino.h"
 
#include <ESP8266WiFi.h>
#include <SimpleFtpServer.h>
 
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASS";
 
 
FtpServer ftpSrv;   //set #define FTP_DEBUG in ESP8266FtpServer.h to see ftp verbose on serial
 
 
void setup(void){
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  Serial.println("");
 
  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
 
  /////FTP Setup, ensure SPIFFS is started before ftp;  /////////
  if (SPIFFS.begin()) {
//    SPIFFS.format();
      Serial.println("SPIFFS opened!");
      ftpSrv.begin("esp8266","esp8266");    //username, password for ftp.  set ports in ESP8266FtpServer.h  (default 21, 50009 for PASV)
  }
}
void loop(void){
  ftpSrv.handleFTP();        //make sure in loop you call handleFTP()!!
}

Seleccione FS en esp32

También puede habilitar LittleFS para esp32 editando la línea en el archivo FtpServerKey.h

1#defineDEFAULT_STORAGE_TYPE_ESP32 STORAGE_SPIFFS

en

1#defineDEFAULT_STORAGE_TYPE_ESP32 STORAGE_LITTLEFS

o esto para FFAT

1#defineDEFAULT_STORAGE_TYPE_ESP32 STORAGE_FFAT

Uso

Aquí para esp32

/*
 *  ESP32 Dev Kit (esp32)
 *  Start FTP server to upload data on SPIFFS
 *  by Mischianti Renzo <https://www.mischianti.org>
 *
 *  https://www.mischianti.org/2019/05/11/wemos-d1-mini-esp8266-integrated-spiffs-filesistem-part-2/
 *
 */
 
#include <WiFi.h>
#include "SPIFFS.h"
 
#include <SimpleFtpServer.h>
 
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASS";
 
 
FtpServer ftpSrv;   //set #define FTP_DEBUG in ESP8266FtpServer.h to see ftp verbose on serial
 
 
void setup(void){
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  Serial.println("");
 
  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
 
  /////FTP Setup, ensure SPIFFS is started before ftp;  /////////
  if (SPIFFS.begin(true)) {
      Serial.println("SPIFFS opened!");
      ftpSrv.begin("esp8266","esp8266");    //username, password for ftp.  set ports in ESP8266FtpServer.h  (default 21, 50009 for PASV)
  }    
}
void loop(void){
  ftpSrv.handleFTP();        //make sure in loop you call handleFTP()!!  
}

Es importante destacar en el código anterior que debemos anotar el nombre de nuestra red wifi así como nuestra clave de acceso ( en el ejemplo esta en negrita) . Igualmente deberemos elegir un login y pwd para acceder al servicio ftp ( en el ejemplo es ESP8266/ESP866).

Esta biblioteca admite solo el modo pasivo y debe forzar solo una conexión a la vez.

Uso FileZilla como cliente, que puede descargarlo aquí ; Es bastante simple de usar y configurar.

Primero, debe continuar Manage site --> New sitey ahora configure este parámetro:

  • Seleccionar FTP como protocolo;
  • Seleccione Use plain FTP (insecure);
  • Establezca su nombre de usuario y contraseña (usted elige eso en el boceto);
  • Que en Trasfer settingsseleccionar Maximun number of connectionigual 1;
  • Ahora conéctese a su dispositivo.

Ahora puede administrar sus SPIFFS con arrastrar y soltar.

Recuerde que SPIFFS no administra carpetas, por lo que todos los archivos deben ser planos.

Prueba

Para verificar la carga, puede usar el boceto simple utilizado en el artículo de SPIFFS vinculado:

/*
 *  WeMos D1 mini (esp8266)
 *  SPIFFS get info, read dir and show all file uploaded
 *  add a data folder to use with esp8266 data uploader
 *  by Mischianti Renzo <https://www.mischianti.org>
 *
 *  https://www.mischianti.org/2019/05/11/wemos-d1-mini-esp8266-integrated-spiffs-filesistem-part-2/
 *
 */
 
#include "Arduino.h"
#include "FS.h"
 
void setup()
{
    Serial.begin(112500);
 
    delay(500);
 
    Serial.println(F("Inizializing FS..."));
    if (SPIFFS.begin()){
        Serial.println(F("done."));
    }else{
        Serial.println(F("fail."));
    }
 
    // To format all space in SPIFFS
    // SPIFFS.format()
 
    // Get all information of your SPIFFS
    FSInfo fs_info;
    SPIFFS.info(fs_info);
 
    Serial.println("File sistem info.");
 
    Serial.print("Total space:      ");
    Serial.print(fs_info.totalBytes);
    Serial.println("byte");
 
    Serial.print("Total space used: ");
    Serial.print(fs_info.usedBytes);
    Serial.println("byte");
 
    Serial.print("Block size:       ");
    Serial.print(fs_info.blockSize);
    Serial.println("byte");
 
    Serial.print("Page size:        ");
    Serial.print(fs_info.totalBytes);
    Serial.println("byte");
 
    Serial.print("Max open files:   ");
    Serial.println(fs_info.maxOpenFiles);
 
    Serial.print("Max path length:  ");
    Serial.println(fs_info.maxPathLength);
 
    Serial.println();
 
    // Open dir folder
    Dir dir = SPIFFS.openDir("/");
    // Cycle all the content
    while (dir.next()) {
        // get filename
        Serial.print(dir.fileName());
        Serial.print(" - ");
        // If element have a size display It else write 0
        if(dir.fileSize()) {
            File f = dir.openFile("r");
            Serial.println(f.size());
            f.close();
        }else{
            Serial.println("0");
        }
    }
}
 
void loop()
{
 
}

Prueba con devolución de llamada

Una característica interesante que agregué recientemente fue la devolución de llamada en alguna acción

/*
 * FtpServer esp8266 and esp32 with SPIFFS
 *
 * AUTHOR:  Renzo Mischianti
 *
 * https://www.mischianti.org/2020/02/08/ftp-server-on-esp8266-and-esp32
 *
 */
 
#ifdef ESP8266
#include <ESP8266WiFi.h>
#elif defined ESP32
#include <WiFi.h>
#include "SPIFFS.h"
#endif
 
#include <SimpleFTPServer.h>
 
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASS";
 
 
FtpServer ftpSrv;   //set #define FTP_DEBUG in ESP8266FtpServer.h to see ftp verbose on serial
 
void _callback(FtpOperation ftpOperation, unsigned int freeSpace, unsigned int totalSpace){
  switch (ftpOperation) {
    case FTP_CONNECT:
      Serial.println(F("FTP: Connected!"));
      break;
    case FTP_DISCONNECT:
      Serial.println(F("FTP: Disconnected!"));
      break;
    case FTP_FREE_SPACE_CHANGE:
      Serial.printf("FTP: Free space change, free %u of %u!\n", freeSpace, totalSpace);
      break;
    default:
      break;
  }
};
void _transferCallback(FtpTransferOperation ftpOperation, const char* name, unsigned int transferredSize){
  switch (ftpOperation) {
    case FTP_UPLOAD_START:
      Serial.println(F("FTP: Upload start!"));
      break;
    case FTP_UPLOAD:
      Serial.printf("FTP: Upload of file %s byte %u\n", name, transferredSize);
      break;
    case FTP_TRANSFER_STOP:
      Serial.println(F("FTP: Finish transfer!"));
      break;
    case FTP_TRANSFER_ERROR:
      Serial.println(F("FTP: Transfer error!"));
      break;
    default:
      break;
  }
 
  /* FTP_UPLOAD_START = 0,
   * FTP_UPLOAD = 1,
   *
   * FTP_DOWNLOAD_START = 2,
   * FTP_DOWNLOAD = 3,
   *
   * FTP_TRANSFER_STOP = 4,
   * FTP_DOWNLOAD_STOP = 4,
   * FTP_UPLOAD_STOP = 4,
   *
   * FTP_TRANSFER_ERROR = 5,
   * FTP_DOWNLOAD_ERROR = 5,
   * FTP_UPLOAD_ERROR = 5
   */
};
 
void setup(void){
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  Serial.println("");
 
  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
 
 
  /////FTP Setup, ensure SPIFFS is started before ftp;  /////////
   
  /////FTP Setup, ensure SPIFFS is started before ftp;  /////////
#ifdef ESP32       //esp32 we send true to format spiffs if cannot mount
  if (SPIFFS.begin(true)) {
#elif defined ESP8266
  if (SPIFFS.begin()) {
#endif
      ftpSrv.setCallback(_callback);
      ftpSrv.setTransferCallback(_transferCallback);
 
      Serial.println("SPIFFS opened!");
      ftpSrv.begin("esp8266","esp8266");    //username, password for ftp.   (default 21, 50009 for PASV)
  }    
}
void loop(void){
  ftpSrv.handleFTP();        //make sure in loop you call handleFTP()!!  
 // server.handleClient();   //example if running a webserver you still need to call .handleClient();
  
}

Es importante destacar en el código anterior que debemos anotar el nombre de nuestra red wifi así como nuestra clave de acceso ( en el ejemplo esta en negrita) . Igualmente deberemos elegir un login y pwd para acceder al servicio ftp ( en el ejemplo es ESP8266/ESP866).

Aquí hay una carga simple de un archivo README.md.

.......
Connected to reef-casa-sopra 
IP address: 192.168.1.127
LittleFS opened!
FTP: Connected!
FTP: Upload start!
FTP: Upload of file README.md byte 1072
FTP: Upload of file README.md byte 3120
FTP: Upload of file README.md byte 3559
FTP: Finish transfer!
FTP: Free space change, free 1019904 of 1036288!


Fuente https://www.mischianti.org/2020/02/08/ftp-server-on-esp8266-and-esp32/

2 comentarios en “Descargar ficheros desde un ESp32 vía ftp

Deja una respuesta