M5Stack Core2をFTPサーバとし、SDカードのファイルを対象として動作させます。FTPクライアントには「FileZilla」を使用(他のFTPクライアントだと再調整が必要かもしれません)し、「PlatformIO」で開発します。

FTPサーバの作成

次のようにFTPサーバ「FtpTest」を作成します。

main.cpp

#include <M5Core2.h>
#include <WiFi.h>
#include <WiFiClient.h>
#include "ESP32FtpServer.h"

const char *ssid = "xxxxx";
const char *password = "xxxxx";

FtpServer ftpSrv;

void setup(void)
{
  M5.begin();
  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());

  ftpSrv.begin("esp8266", "esp8266"); 
}

void loop(void)
{
  ftpSrv.handleFTP();
}

「ESP32FtpServer.cpp」と「ESP32FtpServer.h」は「lovyan03/M5Stack_LovyanLauncher」から取得し、次のように変更しました。

  • 1-11行目にインクルードファイルを示します。M5Stack Core2用のインクルードファイルを使用します。
  • 13行目でデバッグ文を有効にします。
  • 50行目を無効にします。有効にするとファイル名の第一文字が削除されます。

ESP32FtpServer.cpp

#include <M5Core2.h>
#include "ESP32FtpServer.h"

#include <WiFi.h>
#include <WiFiClient.h>
//#include <ESP32WebServer.h>
#include <FS.h>
//#include <SD.h>
//#include <SPIFFS.h>
//#include <SPI.h>
#include <string>

#define FTP_DEBUG

WiFiServer ftpServer(FTP_CTRL_PORT);
WiFiServer dataServer(FTP_DATA_PORT_PASV);

・・・

  //
  //  MLSD - Listing for Machine Processing (see RFC 3659)
  //
  else if (!strcmp(command, "MLSD"))
  {
    if (!dataConnect())
      client.println("425 No data connection MLSD");
    else
    {
      client.println("150 Accepted data connection");
      uint16_t nm = 0;
      //      Dir dir= fs().openDir(cwdName);
      File dir = fs().open(cwdName);
      //  if(!fs().exists(cwdName))
      if ((!dir) || (!dir.isDirectory()))
        client.println("550 Can't open directory " + String(cwdName));
      //        client.println( "550 Can't open directory " +String(parameters) );
      else
      {
        int len = strlen(cwdName);
        if (len > 1)
          len += 1;
        //        while( dir.next())
        File file = dir.openNextFile();
        //        while( dir.openNextFile())
        while (file)
        {
          String fn, fs;
          fn = file.name();
          Serial.println("File Name1 = " + fn);
          // fn = fn.substring(len);
          // Serial.println("File Name2 = " + fn);
          fs = String(file.size());
          if (file.isDirectory())
          {
            data.println("Type=dir;Size=" + fs + ";" + "modify=20000101000000;" + " " + fn);
            //            data.println( "Type=dir;modify=20000101000000; " + fn);
          }
          else
          {
            // data.println( "Type=file;Size=" + fs + ";"+"modify=20000101160656;" +" " + fn);
            data.println("Type=file;Size=" + fs + ";" + "modify=20000101000000;" + " " + fn);
          }
          nm++;
          file = dir.openNextFile();
        }
        client.println("226-options: -a -l");
        client.println("226 " + String(nm) + " matches total");
      }
      data.stop();
    }
  }

FTPサーバの実行

FTPサーバ「FtpTest」を実行すると、シリアルモニタにFTPサーバのIPアドレス「IP address: 192.168.10.110」が表示されるので、 このIPアドレスにより「FileZilla」でアクセスします。FTPのIDとパスワードはとも「esp8266」です。「FileZilla」からFTPサーバをアクセスすると、「FileZilla」は次にように表示します(ダウンロード実行後の表示になっています)。

FTPサーバ「FtpTest」を実行すると、シリアルモニタに次のメッセージが表示されます(「Ftp server waiting for connection on port 21」まで)。

「FileZilla」でアクセスすると、次のように上部ウインドウに表示され、上で示したシリアルモニタの表示に「Client connected!」からのメッセージが表示されます。

SDカードに保存されているファイル「abclldef.txt」をダウンロードします。「FileZilla」からダウンロードすると「FileZilla」で次のメッセージが表示されます。いったんサーバから切断して遅延を行い再接続されます(理由は分かりませんが必ず起こります)。

ダウンロード時のシリアルモニタの表示を次に示します。