My goal is to upload a file from my SD card on a Teensy 3.6 to a remote FTP server via the Airlift shield.
Currently, it works sometimes but is unreliable. Sometimes it loses the data connection and only partially uploads a file.
Can anyone help?
Thanks in advance!
Code: Select all
/* Test code for uploading files to Nova FTP server.
November 2021
*/
#include <SD.h>
#include <SPI.h>
#include <WiFiNINA.h>
#define server "*****************"
// Teensy 3.6 ESP32 connections
#define SPIWIFI SPI // The SPI port
#define SPIWIFI_SS 10 // Chip select pin
#define ESP32_RESETN 35 // Reset pin
#define SPIWIFI_ACK 36 // a.k.a BUSY or READY pin
#define ESP32_GPIO0 -1
// Wifi network details
const char* ssid = "***********";
const char* password = "************";
const int chipSelect = BUILTIN_SDCARD; // SD card chip select pin
int status = WL_IDLE_STATUS;
WiFiClient client;
WiFiClient dclient;
char outBuf[255];
char outCount;
byte clientBuf[32];
int clientCount = 0;
unsigned int hiPort, loPort;
File fh;
void setup() {
Serial.begin(115200);
while (!Serial);
// Assign Teensy SPI pins
// First reassign pin 13 to the default so that it is not SCK
CORE_PIN13_CONFIG = PORT_PCR_MUX(0);
// and then reassign pin 14 to SCK
CORE_PIN14_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);
// Check for the WiFi module:
WiFi.setPins(SPIWIFI_SS, SPIWIFI_ACK, ESP32_RESETN, ESP32_GPIO0, &SPIWIFI);
if (WiFi.status() == WL_CONNECTED) {
Serial.println(F("Connected to WiFi module."));
}
while (WiFi.status() == WL_NO_MODULE) {
Serial.println(F("Communication with WiFi module failed!"));
delay(1000);
}
// Attempt to connect to Wifi network:
Serial.print(F("Attempting to connect to SSID: "));
Serial.println(ssid);
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
do {
status = WiFi.begin(ssid, password);
delay(100); // wait until connected
} while (status != WL_CONNECTED);
Serial.println(F("Connected to WiFi network."));
}
void loop() {
FTP();
while (1);
}
byte FTP() {
Serial.println(F("Initialising SD card..."));
if (!SD.begin(chipSelect)) {
Serial.println(F("Initialization failed!"));
while (1);
}
Serial.println(F("Success."));
// Open data file for reading
fh = SD.open("DATALOG.txt", FILE_READ);
if (!fh)
{
Serial.println(F("SD open fail"));
return 0;
}
Serial.println(F("File open"));
// Find the start of the file
if (!fh.seek(0))
{
Serial.println(F("Rewind fail"));
fh.close();
return 0;
}
// Connect to the server
Serial.println(F("SD opened"));
if (client.connect(server, 21)) {
Serial.println(F("Connected to server"));
}
else {
fh.close();
Serial.println(F("Command connection failed"));
return 0;
}
if (!eRcv()) return 0;
client.println(F("USER **********"));
if (!eRcv()) return 0;
client.println(F("PASS ***********"));
if (!eRcv()) return 0;
client.println(F("SYST"));
if (!eRcv()) return 0;
client.println(F("Type I"));
if (!eRcv()) return 0;
Serial.println(F("Data connection."));
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"));
}
}
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;
}
// if (!eRcv()) return 0;
client.print(F("STOR "));
client.println(F("DATALOG.txt"));
if (!eRcv())
{
Serial.println(F("Failed writing data."));
dclient.stop();
return 0;
}
// Find the start of the file
if (!fh.seek(0))
{
Serial.println(F("Rewind fail"));
fh.close();
return 0;
}
while (fh.available()) {
for (int i = 0; i < 32; i++) {
int fileData = fh.read();
while (fileData == -1) {
Serial.println(i);
Serial.println(F("SD -1 error"));
int posFile = fh.position();
Serial.println(posFile);
fh.close();
Serial.println(F("File close"));
delay(1000);
fh = SD.open("DATALOG.txt", FILE_READ);
fh.seek(posFile);
fileData = fh.read();
Serial.println(fileData);
}
clientBuf[clientCount] = byte(fileData);
clientCount++;
}
if (clientCount > 1)
{
size_t checkWrite = dclient.write(clientBuf, 32);
if (checkWrite == 0) {
Serial.println(F("Fatal FTP Error!"));
if (!dclient.connected()) {
Serial.println("Disconnected");
}
dclient.stop();
dclient.connect(server, hiPort);
return 0;
}
if (checkWrite != 32 && checkWrite > 0) {
int pointer = checkWrite;
delay(100);
dclient.write(clientBuf + pointer, 32 - pointer);
}
clientCount = 0;
}
}
if (clientCount > 0) {
dclient.write(clientBuf, clientCount);
}
dclient.stop();
if (!eRcv()) return 0;
return 1;
}
byte eRcv()
{
byte respCode;
byte thisByte;
delay(400);
while (!client.available()) {
delay(1);
}
respCode = client.peek();
outCount = 0;
while (client.available())
{
thisByte = client.read();
Serial.write(thisByte);
if (outCount < 254)
{
outBuf[outCount] = thisByte;
outCount++;
outBuf[outCount] = 0;
}
}
if (respCode >= '4')
{
efail();
return 0;
}
return 1;
}
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"));
}