Upload files to FTP server via Adafruit Airlift Wifi Shield + Teensy 3.6

Hello,

I am currently using a Teensy 3.6 with an Adafuirt Airlift Wifi Shield to upload files to a FTP server from the SD card on the Teensy.
Sometimes it works and sometimes the data connection is lost and the file is only partially uploaded. It doesn't fail at the same point each time and as I mentioned, sometimes it works fine.

Can anyone help me understand why this might be happening please?
My code is based off the FTP code in Arduino Playground.

/* 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"));
}

Quite often poor powering is the reason for projects running for some limited time and then going wrong. My suggestion is that You post the schematics for this rigging.
3.3 volt mixed with 5 volt circuits?


Thanks, the shield itself is powered from the 5V coming from the USB connector powering the Teensy.