Server FTP su esp8266 ed esp32

Spread the love

Quando sviluppo una nuova soluzione, vorrei dividere l’applicazione in layer e quindi poter focalizzare la mia attenzione su un solo aspetto alla volta.

In dettaglio separo il livello REST (scritto all’interno del microcontrollore) e il Front-End (scritto in Angular, React / Redux o vanilla JS), quindi vorrei caricare la nuova interfaccia web direttamente sul microcontrollore via FTP.

FTP file transfer on esp8266 or esp32

Per informazioni statiche (pagine Web per esempio), che non cambiano frequentemente, esp8266 o esp32 possono sfruttare lo SPIFFS interno (SPI Flash File System) e puoi caricare dati tramite Arduino IDE come spiegato nell’articolo “WeMos D1 mini (esp8266): sistema operativo integrato SPIFFS” per l’esp8266 “ESP32: FileSystem SPIFFS integrato” per l’esp32 oppure il LittleFS “WeMos D1 mini (esp8266): FileSystem integrato LittleFS” per esp8266 o “ESP32: filesystem integrato LittleFS” per esp32 o FFAT “ESP32: filesystem integrato FFat (Fat/exFAT)” oppure con Arduino per caricare file sull’SD, per operazioni veloci e supporto futuro trovo utile il protocollo FTP.

Ho trovato una semplice libreria che funziona abbastanza bene e non è affamata di risorse, puoi trovarla qui.

Nel tempo questa libreria diventa buggata e con un supporto molto basso quindi l’ho aggiustata e ora puoi recuperare la libreria da qui.

Libreria

La mia nuova libreria è ora disponibile tramite il Library Manager dell’Arduino IDE

SimpleFTPServer sull'Arduino library manager
SimpleFTPServer sull’Arduino library manager

Ma anche su GitHub.

Fare clic sul pulsante DOWNLOADS nell’angolo in alto a destra, rinominare la cartella non compressa PCF8574.

Verificare che la cartella SimpleFTPServer contenga FtpServer.cpp, FtpServer.h, FtpServerKey.h e SimpleFTPServer.h .

Collocare la cartella della libreria SimpleFTPServer come / librerie / cartella.

Potrebbe essere necessario creare la sottocartella librerie se è la tua prima libreria.

Riavvia l’IDE.

Selezionare il FS su esp8266

Puoi inoltre abilitare il LittleFS per l’esp8266, andando a modificare nel file FtpServerKey.h la riga

	#define DEFAULT_STORAGE_TYPE_ESP8266 STORAGE_SPIFFS

in

	#define DEFAULT_STORAGE_TYPE_ESP8266 STORAGE_LITTLEFS

Uso

Ecco un esempio per esp8266

/*
 *  WeMos D1 mini (esp8266)
 *  Start FTP server to upload data on SPIFFS
 *  by Mischianti Renzo <https://mischianti.org>
 *
 *  https://mischianti.org/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()!!
}

Selezionare il FS su esp32

Puoi abilitare il LittleFS per l’esp32, andando a modificare nel file FtpServerKey.h la riga

	#define DEFAULT_STORAGE_TYPE_ESP32 STORAGE_SPIFFS

in

	#define DEFAULT_STORAGE_TYPE_ESP32 STORAGE_LITTLEFS

or questo per FFAT

	#define DEFAULT_STORAGE_TYPE_ESP32 STORAGE_FFAT

Ecco qui la lista completa delle opzioni.

#define STORAGE_SDFAT1 		1 	// Library SdFat version 1.4.x
#define STORAGE_SDFAT2 		2 	// Library SdFat version >= 2.0.2
#define STORAGE_SPIFM  		3 	// Libraries Adafruit_SPIFlash and SdFat-Adafruit-Fork
#define STORAGE_FATFS  		4 	// Library FatFs
#define STORAGE_SD 			5 	// Standard SD library (suitable for Arduino esp8266 and esp32
#define STORAGE_SPIFFS 		6 	// SPIFFS
#define STORAGE_LITTLEFS 	7 	// LITTLEFS
#define STORAGE_SEEED_SD 	8 	// Seeed_SD library
#define STORAGE_FFAT  		9 	// ESP32 FFAT
#define STORAGE_SD_MMC		10 	// SD_MMC library

Naturalmente non tutte compatibili con i nostri microcontrollori.

Uso

Qui per esp32

/*
 *  ESP32 Dev Kit (esp32)
 *  Start FTP server to upload data on SPIFFS
 *  by Mischianti Renzo <https://mischianti.org>
 *
 *  https://mischianti.org/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()!!  
}

Questa libreria supporta solo la modalità passiva ed è necessario forzare solo una connessione alla volta.

Uso FileZilla come client, puoi scaricarlo qui, è abbastanza semplice sia da usare che configurare.

Filezilla configuration for access esp8266, select plain FTP on Manage Site

Per prima cosa devi andare su Manage site --> New site e ora imposta questo parametro:

  • Seleziona FTP come protocollo;
  • Seleziona Use plain FTP (insecure);
  • Imposta la tua login e password (specificate sullo sketch);
  • Ora in Trasfer settings seleziona Maximun number of connection uguale a 1;
  • Ora connettiti il tuo dispositivo.
Filezilla configuration for access esp8266, select max num connections

Ora puoi gestire il tuo SPIFFS con il drag and drop.

Ricorda che SPIFFS non gestisce le cartelle, quindi tutti i file devono essere piatti.

Test

Per verificare il caricamento è possibile utilizzare il semplice sketch utilizzato nell’articolo SPIFFS sopra lincato:

/*
 *  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://mischianti.org>
 *
 *  https://mischianti.org/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()
{

}

Test con callback

Un’interessante feature che ho aggiunto di recente sono le callback su alcune azioni

/*
 * FtpServer esp8266 and esp32 with SPIFFS
 *
 * AUTHOR:  Renzo Mischianti
 *
 * https://mischianti.org/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();
 
}

Qui un semplice upload del file 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!

Grazie.

  1. Libreria SimpleFTPServer library: guida esp32 e esp8266
  2. Libreria SimpleFTPServer: guida WioTerminal

Spread the love

7 Risposte

  1. Gabryx ha detto:

    Ok funziona tutto, 300Kb al secondo di transfer rate con Esp32 Dev Kit V1 e Ili9488 touch screen, librerie TFT_eSPI e LVGL.
    Unica cosa che non mi sembra a posto è un warning in fase di compilazione con Arduino Ide:
    SimpleFTPServer/FtpServer.h:639:30: warning: ‘packed’ attribute ignored for field of type ‘uint8_t [2048]’ {aka ‘unsigned char [2048]’} [-Wattributes]
    … bisogna cambiare la dichiarazione in FtpServerKey?
    Grazie e ciao

  2. Gabryx ha detto:

    Oppure quella in FtpServer.h
    uint8_t __attribute__((packed, aligned(4))) // need to be aligned to 32bit for Esp8266 SPIClass::transferBytes()
    buf[ FTP_BUF_SIZE ]; // data buffer for transfers

    • Renzo Mischianti ha detto:

      Ciao Gabryx,
      quello è solo uno warning, per altre architetture è utile, per l’esp32 andrebbe rimosso, ma visto che lo fa in automatico il compilatore l’ho lasciato.
      Vedremo nei rilasci futuri.
      Ciao Renzo

  3. Francesco ha detto:

    Buongiorno,

    è possibile utilizzare solo la connessione cablata con un w5500 su esp8266 o esp32? ho provato ad adattare gli esempi proposti con la libreria ma non sono riuscito a venirne a capo.

    Grazie
    Francesco

    • Renzo Mischianti ha detto:

      Ciao Francesco,
      devi modificare EMailSenderKey.h in questo modo:

      // esp8266 configuration
      #ifndef DEFAULT_FTP_SERVER_NETWORK_TYPE_ESP8266
      #define DEFAULT_FTP_SERVER_NETWORK_TYPE_ESP8266 NETWORK_W5100
      #define DEFAULT_STORAGE_TYPE_ESP8266 STORAGE_LITTLEFS
      #endif
      // esp32 configuration
      #ifndef DEFAULT_FTP_SERVER_NETWORK_TYPE_ESP32
      #define DEFAULT_FTP_SERVER_NETWORK_TYPE_ESP32 NETWORK_W5100
      #define DEFAULT_STORAGE_TYPE_ESP32 STORAGE_FFAT
      #endif

      Fammi sapere.
      Ciao Renzo

      • Francesco ha detto:

        Ciao Renzo,
        ho provato a cambiare il file FtpServerKey.h (intendevi questo e non EMailSenderKey.h giusto?) seguendo le tue istruzione ma la compilazione non va mai a buon fine. A dire il vero non va a buon fine qualunque sia il valore che metto in DEFAULT_FTP_SERVER_NETWORK_TYPE_ESP32 o DEFAULT_FTP_SERVER_NETWORK_TYPE_ESP8266.
        Sconfortato o anche provato a prendere una ENC28j60 e provare l’esempio ESP32_FFAT_enc28j60.ino ma in questo caso non riesce mai a montare FFat, e se modifico sostituendo FFat con SPIFFS o LittleFS al momento del ftpSrv.begin la scheda va in loop.

        Saluti disperati
        Francesco

        • Renzo Mischianti ha detto:

          Hehehehe.. diciamo che ho poche informazioni per poterti aiutare..
          Apri un Topic sul forum e posta il tuo codice e come hai “configurato” il microcontrollore sull’arduino IDE.
          Ciao Renzo

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *