Server FTP su esp8266 ed esp32
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.
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
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.
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
selezionaMaximun number of connection
uguale a 1; - Ora connettiti il tuo dispositivo.
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.
- Libreria SimpleFTPServer library: guida esp32 e esp8266
- Libreria SimpleFTPServer: guida WioTerminal
- Server FTP su STM32 con W5500, ENC28J60, scheda SD e memoria flash SPI
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
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
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
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
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
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
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