Add FTP Client library (original) (raw)

Hi, I like to adapt http://playground.arduino.cc/Code/FTP to ESP8266.
Most part of the adapted program WiFi_FTP_Client.ino works, but there is a compiler error left,
which I can not resolve.
Most part of the program works, except the file data transfer to the FTP server.
If I declare const char clientBuf[64] = "aa";
instead of byte clientBuf[64];, it works, but that is not what I need.
If I use the library Ethernet.h instead of ESP8266WiFi.h it compiles OK, but no data transfer.
By the way, if I compile the original program FTP.ino with Ethernet.h, I get no compiler error.
Please see the error messages (Arduino 1.6.5 and 1.6.6):

In file included from /Volumes/DAT/Users/rudi/Documents/Arduino/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.h:32:0,

             from /Volumes/DAT/Users/rudi/Documents/Arduino/wifi_FTP_client/wifi_FTP_client.ino:10:

/Volumes/DAT/Users/rudi/Documents/Arduino/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.h: In instantiation of 'size_t WiFiClient::write(T&, size_t) [with T = unsigned char [64]; size_t = unsigned int]':

/Volumes/DAT/Users/rudi/Documents/Arduino/wifi_FTP_client/wifi_FTP_client.ino:285:34: required from here

/Volumes/DAT/Users/rudi/Documents/Arduino/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.h:119:36: error: request for member 'available' in 'source', which is of non-class type 'unsigned char [64]'

 size_t left = source.available();
                                ^

/Volumes/DAT/Users/rudi/Documents/Arduino/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.h:123:5: error: request for member 'read' in 'source', which is of non-class type 'unsigned char [64]' source.read(buffer.get(), will_send); ^

Who can help me to solve that puzzle please?
Regards, Rudolf

The program with the error, the error lines are marked:

/* FTP passive client for IDE v1.0.1 and w5100/w5200 http://playground.arduino.cc/Code/FTP Modified 6 June 2015 by SurferTim

You can pass flash-memory based strings to Serial.print() by wrapping them with F().

2015-12-09 Rudolf Reuter, adapted to ESP8266 NodeMCU */ #include <ESP8266WiFi.h> // #include <Ethernet.h> #include <FS.h>

// comment out next line to write to SD from FTP server #define FTPWRITE

// Set these to your desired softAP credentials. They are not configurable at runtime. const char *ssid = "FRITZ-7170R"; const char *password = ".............";

boolean debug = false; // true = more messages //boolean debug = true;

// LED is needed for failure signalling const short int BUILTIN_LED2 = 16; //GPIO16 on NodeMCU (ESP-12)

unsigned long startTime = millis();

// provide text for the WiFi status const char *str_status[]= { "WL_IDLE_STATUS", "WL_NO_SSID_AVAIL", "WL_SCAN_COMPLETED", "WL_CONNECTED", "WL_CONNECT_FAILED", "WL_CONNECTION_LOST", "WL_DISCONNECTED" };

// provide text for the WiFi mode const char *str_mode[]= { "WIFI_OFF", "WIFI_STA", "WIFI_AP", "WIFI_AP_STA" };

// this must be unique byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x59, 0x67 };

// change to your network settings IPAddress ip( 192, 168, 17, 231 ); IPAddress gateway( 192, 168, 17, 1 ); IPAddress subnet( 255, 255, 255, 0 );

// change to your server IPAddress server( 192, 168, 17, 72 );

WiFiClient client; WiFiClient dclient; //EthernetClient client; // from Arduino FTP.ino //EthernetClient dclient; // from Arduino FTP.ino

char outBuf[128]; char outCount;

// change fileName to your file (8.3 format!) String fileName = "TimeTemp.txt"; String path = "/TimeTemp.txt";

// SPIFFS file handle File fh;

void signalError() { // loop endless with LED blinking in case of error while(1) { digitalWrite(BUILTIN_LED2, LOW); delay(300); // ms digitalWrite(BUILTIN_LED2, HIGH); delay(300); // ms } }

//format bytes String formatBytes(size_t bytes) { if (bytes < 1024) { return String(bytes) + "B"; } else if (bytes < (1024 * 1024)) { return String(bytes / 1024.0) + "KB"; } else if (bytes < (1024 * 1024 * 1024)) { return String(bytes / 1024.0 / 1024.0) + "MB"; } else { return String(bytes / 1024.0 / 1024.0 / 1024.0) + "GB"; } }

//----------------------- WiFi handling void connectWifi() { Serial.print("Connecting as wifi client to SSID: "); Serial.println(ssid);

// use in case of mode problem WiFi.disconnect(); // switch to Station mode if (WiFi.getMode() != WIFI_STA) { WiFi.mode(WIFI_STA); }

WiFi.begin ( ssid, password );

if (debug ) WiFi.printDiag(Serial);

// ... Give ESP 10 seconds to connect to station. unsigned long startTime = millis(); while (WiFi.status() != WL_CONNECTED && millis() - startTime < 10000) { delay(500); Serial.print("."); } Serial.println(""); // Check connection if (WiFi.status() == WL_CONNECTED) { Serial.print("WiFi connected; IP address: "); Serial.println(WiFi.localIP()); } else { Serial.print("WiFi connect failed to ssid: "); Serial.println(ssid); Serial.print("WiFi password <"); Serial.print(password); Serial.println(">"); Serial.println("Check for wrong typing!"); } } // connectWiFi()

//----------------- FTP fail void efail() { byte thisByte = 0;

client.println(F("QUIT"));

while (!client.available()) delay(1);

while (client.available()) { thisByte = client.read(); Serial.write(thisByte); }

client.stop(); Serial.println(F("Command disconnected")); fh.close(); Serial.println(F("SD closed")); } // efail

//-------------- FTP receive byte eRcv() { byte respCode; byte thisByte;

while (!client.available()) delay(1);

respCode = client.peek();

outCount = 0;

while (client.available()) { thisByte = client.read(); Serial.write(thisByte);

if (outCount < 127) {
  outBuf[outCount] = thisByte;
  outCount++;
  outBuf[outCount] = 0;
}

}

if (respCode >= '4') { efail(); return 0; } return 1; } // eRcv()

//--------------- FTP handling byte doFTP() {

#ifdef FTPWRITE fh = SPIFFS.open(path, "r"); #else SPIFFS.remove(path); fh = SPIFFS.open(path, "w"); #endif

if (!fh) { Serial.println(F("SPIFFS open fail")); return 0; }

#ifndef FTPWRITE if (!fh.seek(0)) { Serial.println(F("Rewind fail")); fh.close(); return 0; } #endif

Serial.println(F("SPIFFS opened"));

if (client.connect(server, 21)) { // 21 = FTP server Serial.println(F("Command connected")); } else { fh.close(); Serial.println(F("Command connection failed")); return 0; }

if (!eRcv()) return 0; Serial.println("Send USER"); client.println(F("USER rudi"));

if (!eRcv()) return 0; Serial.println("Send PASSWORD"); client.println(F("PASS xxxxxxxx"));

if (!eRcv()) return 0; Serial.println("Send SYST"); client.println(F("SYST"));

if (!eRcv()) return 0; Serial.println("Send Type I"); client.println(F("Type I"));

if (!eRcv()) return 0; Serial.println("Send PASV"); client.println(F("PASV"));

if (!eRcv()) return 0;

char *tStr = strtok(outBuf, "(,"); int array_pasv[6]; for ( int i = 0; i < 6; i++) { tStr = strtok(NULL, "(,"); array_pasv[i] = atoi(tStr); if (tStr == NULL) { Serial.println(F("Bad PASV Answer")); } } unsigned int hiPort, loPort; hiPort = array_pasv[4] << 8; loPort = array_pasv[5] & 255;

Serial.print(F("Data port: ")); hiPort = hiPort | loPort; Serial.println(hiPort);

if (dclient.connect(server, hiPort)) { Serial.println(F("Data connected")); } else { Serial.println(F("Data connection failed")); client.stop(); fh.close(); return 0; }

#ifdef FTPWRITE Serial.println("Send STOR filename"); client.print(F("STOR ")); client.println(fileName); #else client.print(F("RETR ")); client.println(fileName); #endif

if (!eRcv()) { dclient.stop(); return 0; }

#ifdef FTPWRITE Serial.println(F("Writing")); //byte clientBuf[64]; //const char clientBuf[64] = "aa"; uint8_t clientBuf[64]; //char clientBuf[64]; //unsigned int clientCount = 0; size_t clientCount = 0;

while (fh.available()) { clientBuf[clientCount] = fh.read(); clientCount++; if (clientCount > 63) { dclient.write(clientBuf, 64); //------------ ERROR clientCount = 0; delay(1); } } if (clientCount > 0) dclient.write(clientBuf, clientCount); //----- ERROR

#else while (dclient.connected()) { while (dclient.available()) { char c = dclient.read(); fh.write(c); Serial.write(c); } } #endif

dclient.stop(); Serial.println(F("Data disconnected"));

if (!eRcv()) return 0;

client.println(F("QUIT"));

if (!eRcv()) return 0;

client.stop(); Serial.println(F("Command disconnected"));

fh.close(); Serial.println(F("SPIFS closed")); return 1; } // doFTP()

void readSPIFFS() { fh = SPIFFS.open(fileName, "r");

if (!fh) { Serial.println(F("SPIFFS open fail")); return; }

while (fh.available()) { Serial.write(fh.read()); }

fh.close(); } // readSPIFFS()

void setup() { delay(1000); Serial.begin(115200); delay(1000); Serial.println("Sync,Sync,Sync,Sync,Sync"); delay(500); Serial.println(); // signal start pinMode(BUILTIN_LED2, OUTPUT); digitalWrite(BUILTIN_LED2, LOW); delay(100); // ms digitalWrite(BUILTIN_LED2, HIGH); delay(300); // ms

Serial.print("Chip ID: 0x"); Serial.println(ESP.getChipId(), HEX);

Serial.println ( "Connect to Router requested" ); connectWifi(); if (WiFi.status() == WL_CONNECTED) { Serial.print("WiFi mode: "); Serial.println(str_mode[WiFi.getMode()]); Serial.print ( "Status: " ); Serial.println (str_status[WiFi.status()]); // signal WiFi connect digitalWrite(BUILTIN_LED2, LOW); delay(300); // ms digitalWrite(BUILTIN_LED2, HIGH);
} else { Serial.println(""); Serial.println("WiFi connect failed, push RESET button."); signalError(); }

//Ethernet.begin(mac, ip, gateway, gateway, subnet); // from Arduino FTP.ino

if (!SPIFFS.begin()) { Serial.println("SPIFFS failed, needs formatting"); signalError(); }

fh = SPIFFS.open(path, "r"); if (!fh) { Serial.println(F("SPIFFS open fail")); signalError(); } else fh.close();

Serial.println(F("Ready. Press f or r")); } // setup()

void loop() { byte inChar;

if (Serial.available() > 0) { inChar = Serial.read(); }

if (inChar == 'f') { if (doFTP()) Serial.println(F("FTP OK")); else Serial.println(F("FTP FAIL")); }

if (inChar == 'r') { String fileNameDir; Dir dir = SPIFFS.openDir("/"); while (dir.next()) { fileNameDir = dir.fileName(); size_t fileSize = dir.fileSize(); Serial.printf("FS File: %s, size: %s\n", fileNameDir.c_str(), formatBytes(fileSize).c_str()); } } delay(10); }

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.