Skip to content

Instantly share code, notes, and snippets.

@chaeplin
Created April 23, 2016 09:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chaeplin/24f25984b5115ce778af3bd40da006bc to your computer and use it in GitHub Desktop.
Save chaeplin/24f25984b5115ce778af3bd40da006bc to your computer and use it in GitHub Desktop.
WiWi_FTP_Client.ino
// File: WiWi_FTP_Client.ino for ESP8266 NodeMCU
/*
Original Arduino: FTP passive client
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, with the help of Markus.
*/
#include <ESP8266WiFi.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 = "xxxxxxxx";
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" };
// change to your server
IPAddress server( 192, 168, 17, 72 );
WiFiClient client;
WiFiClient dclient;
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(boolean upload) {
if (upload) {
fh = SPIFFS.open(path, "r");
} else {
SPIFFS.remove(path);
fh = SPIFFS.open(path, "w");
}
if (!fh) {
Serial.println(F("SPIFFS open fail"));
return 0;
}
if (upload) {
if (!fh.seek((uint32_t)0, SeekSet)) {
Serial.println(F("Rewind fail"));
fh.close();
return 0;
}
}
if (debug) 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;
if (debug) Serial.println("Send USER");
client.println(F("USER rudi"));
if (!eRcv()) return 0;
if (debug) Serial.println("Send PASSWORD");
client.println(F("PASS ozasol900"));
if (!eRcv()) return 0;
if (debug) Serial.println("Send SYST");
client.println(F("SYST"));
if (!eRcv()) return 0;
if (debug) Serial.println("Send Type I");
client.println(F("Type I"));
if (!eRcv()) return 0;
if (debug) 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;
if (debug) Serial.print(F("Data port: "));
hiPort = hiPort | loPort;
if (debug) 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;
}
if (upload) {
if (debug) Serial.println("Send STOR filename");
client.print(F("STOR "));
client.println(fileName);
} else {
if (debug) Serial.println("Send RETR filename");
client.print(F("RETR "));
client.println(fileName);
}
if (!eRcv()) {
dclient.stop();
return 0;
}
if (upload) {
if (debug) Serial.println(F("Writing"));
// for faster upload increase buffer size to 1460
//#define bufSizeFTP 64
#define bufSizeFTP 1460
uint8_t clientBuf[bufSizeFTP];
//unsigned int clientCount = 0;
size_t clientCount = 0;
while (fh.available()) {
clientBuf[clientCount] = fh.read();
clientCount++;
if (clientCount > (bufSizeFTP - 1)) {
dclient.write((const uint8_t *) &clientBuf[0], bufSizeFTP);
clientCount = 0;
delay(1);
}
}
if (clientCount > 0) dclient.write((const uint8_t *) &clientBuf[0], clientCount);
} else {
while (dclient.connected()) {
while (dclient.available()) {
char c = dclient.read();
fh.write(c);
if (debug) Serial.write(c);
}
}
}
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();
if (debug) 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();
}
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 d, u or r"));
} // setup()
void loop() {
byte inChar;
if (Serial.available() > 0) {
inChar = Serial.read();
}
boolean upload = true; // false = download
if (inChar == 'd') {
upload = false;
if (doFTP(upload)) Serial.println(F("FTP OK"));
else Serial.println(F("FTP FAIL"));
}
if (inChar == 'u') {
upload = true;
if (doFTP(upload)) 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);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment