FTP server on esp8266 and esp32 (original) (raw)

When I develop a new solution, I’d like to divide the application into layers, and so I’d like to focus my attention on only one aspect at a time.

In detail, I separate the REST layer (written inside the microcontroller) and the Front-End (composed in Angular, React/Redux, or vanilla JS), so I’d like to upload a new web interface directly to the microcontroller via FTP.

FTP file transfer on esp8266 or esp32

For static information (Web pages, for example) that do not change frequently, esp8266 or esp32 have internal SPIFFS (SPI Flash File System). You can upload data via Arduino IDE as explained in the article “WeMos D1 mini (esp8266), integrated SPIFFS Filesystem” for esp8266 or “ESP32: integrated SPIFFS FileSystem” for esp32 or with LittleFS “WeMos D1 mini (esp8266), integrated LittleFS Filesystem” for esp8266 or “ESP32: integrated LittleFS FileSystem” for esp32 or “ESP32: integrated FFat (FAT/exFAT) FileSystem” but for fast operation and future support It usefully uses FTP.

I find a simple library that works quite well, and It’s not hungry for resources; you can find It here.

In time, this library becomes buggy and had deficient support, so I fix It, and now you can retrieve the library from here.

Library

The library is available directly from the Library Manager of Arduino IDE.

SimpleFTPServer on Arduino library manager

SimpleFTPServer on Arduino library manager

Or the source code from GitHub.

You can find my library here.

To download.

Click the DOWNLOADS button in the top right corner, and rename the uncompressed folder SimpleFTPServer.

Check that the SimpleFTPServer contains FtpServer.cpp, FtpServer.h, FtpServerKey.h e SimpleFTPServer.h .

Place the SimpleFTPServer library folder in your /libraries/ folder.

You may need to create the libraries subfolder if it’s your first library.

Restart the IDE.

Select FS on esp8266

You can also enable LittleFS for esp8266 by editing the line in the FtpServerKey.h file

#define DEFAULT_STORAGE_TYPE_ESP8266 STORAGE_SPIFFS

in

#define DEFAULT_STORAGE_TYPE_ESP8266 STORAGE_LITTLEFS

Usage

Here is an example for esp8266

/*

#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()!! }

Select FS on esp32

You can also enable LittleFS for esp32 by editing the line in the FtpServerKey.h file

#define DEFAULT_STORAGE_TYPE_ESP32 STORAGE_SPIFFS

in

#define DEFAULT_STORAGE_TYPE_ESP32 STORAGE_LITTLEFS

or this for FFAT

#define DEFAULT_STORAGE_TYPE_ESP32 STORAGE_FFAT

Here the complete list of options.

#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

Not all are compatible with our device.

Usage

Here for esp32

/*

#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()!!
}

This library support only passive mode and you must force only one connection at time.

I use FileZilla as a client, and you can download It here; It is pretty simple to use and configure.

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

First, you must go on Manage site --> New site and now set this parameter:

Filezilla configuration for access esp8266, select max num connections

Now, you can manage your SPIFFS with drag and drop.

Remember that SPIFFS does not manage folders, so all files must be flat.

Test

To check the upload, you can use the simple sketch used in the SPIFFS article linked up:

/*

#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 with callback

An interesting feature I added recently was the callback on some action

/*

#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,

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

}

Here is a simple upload of a README.md file.

....... 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!

Thanks.

  1. SimpleFTPServer library: esp32 and esp8266 how to
  2. SimpleFTPServer library: WioTerminal how to
  3. FTP server on STM32 with w5500, enc28j60, SD Card, and SPI Flash
  4. MultiFTPServer Library Tutorial for ESP32, Raspberry Pi Pico, Arduino, rp2040, esp8266 and STM32