FTP with electron

Hi,
I am working with particle electron 3G to send files to FTP server. I have read the AT command datasheet for onboard ublox gsm modem and found that first you have to create file at file system of gsm modem and then transfer it from there using “AT+UFTPC=5,” command. I am having trouble writing data from sdcard file to gsm modem file system. I have written this code to write data from sdcard file to gsm modem file system. Also, i have tried similar approach with Arduino MKR 1400 board which also has onboard gsm modem from ublox and i am able to upload file to FTP server. Can anyone help me resolve this issue?
Thank you.

    // This #include statement was automatically added by the Particle IDE.
#include <SdFat.h>
#include "cellular_hal.h"
#include "Particle.h"
// Pick an SPI configuration.
// See SPI configuration section below (comments are for photon).
#define SPI_CONFIGURATION 0

//------------------------------------------------------------------------------
// Setup SPI configuration.
#if SPI_CONFIGURATION == 0
// Primary SPI with DMA
// SCK => A3, MISO => A4, MOSI => A5, SS => A2 (default)
SdFat sd;
const uint8_t chipSelect = SS;
#elif SPI_CONFIGURATION == 1
// Secondary SPI with DMA
// SCK => D4, MISO => D3, MOSI => D2, SS => D1
SdFat sd(1);
const uint8_t chipSelect = D1;
#elif SPI_CONFIGURATION == 2
// Primary SPI with Arduino SPI library style byte I/O.
// SCK => A3, MISO => A4, MOSI => A5, SS => A2 (default)
SdFatLibSpi sd;
const uint8_t chipSelect = SS;
#elif SPI_CONFIGURATION == 3
// Software SPI.  Use any digital pins.
// MISO => D5, MOSI => D6, SCK => D7, SS => D0
SdFatSoftSpi<D5, D6, D7> sd;
const uint8_t chipSelect = D0;
#endif  // SPI_CONFIGURATION
//------------------------------------------------------------------------------

File myFile;

#define MAX_PHONE_NUMBER    14
#define TIMEOUT 10000


String apn = "airtelgprs.com";
String username = "";
String password = "";
STARTUP(cellular_credentials_set(apn, username, password, NULL));

char PhoneNumber[MAX_PHONE_NUMBER] = "";
char szReturn[32] = "";
char data[512];
int file_size_sd;

void setup() 
{
    Serial.begin(9600);
    // Wait for USB Serial 
    while (!Serial) 
    {
        SysCall::yield();
    }
    
	Serial.println("Starting cellular, waiting 10s.");
	Cellular.on();
	delay(5000);
	Serial.println("Cellular started. Ready to receive AT commands.");
	Serial.println();
	
    if (!sd.begin(chipSelect, SPI_HALF_SPEED))
    {
        sd.initErrorHalt();
    }

    // open the file for write at end like the "Native SD library"
    if (!myFile.open("data.txt", O_RDWR)) 
    {
        sd.errorHalt("opening data.txt for write failed");
    }
    
    if (myFile) 
    {
        file_size_sd = myFile.size();
        Serial.println(file_size_sd);
        delay(2000);

        Cellular.command(callback, szReturn, 1000, "AT+ULSTFILE=\r\n");                 //list file on gsm file system
        Cellular.command(callback, szReturn, 1000, "AT+ULSTFILE=1\r\n");                //Get free space in the file system (in bytes)
        Cellular.command(callback, szReturn, 1000, "AT+UDWNFILE=\"data.txt\",500000\r\n");      //create file o gsm file system (500kb)   
        Serial.println("Copy file data");           

        while (myFile.available() > 0)  
        {
        Cellular.command(callback, szReturn,200, (const char*)myFile.read());
        }

        Serial.println("Done Writing");
        Serial.println("Close file!");
        myFile.close();
  }

}

void loop()
{

}


int callback(int type, const char* buf, int len, char* param)
{  
    Serial.print("Return: ");
    Serial.write((const uint8_t*)buf, len);
    Serial.println();
    
    return WAIT;
}

I believe you will find it impossible to do without building a custom version of the system firmware.

The problem is that to upload a file to the u-blox file system you need to send the raw data immediately after the command, and you can’t do that using Cellular.command().

There’s an internal function electronMDM.writeFile that does that, but the function is not exposed to user firmware through the HAL, so you can’t call it.

1 Like

Oh, i didnt knew about that internal function. I have seen your solution for FTP file upload on the forum, As i am trying to upload file saved on the sdcard module interfaced to electron is your solution the best way to implement file upload to FTP server using electron.

I’m not a fan of FTP because there’s a huge amount of overhead vs. using HTTP POST. However, the software-based solution I posted elsewhere does work, so that’s a reasonable option if you need to use FTP.

Thaks a lot for your quick response. :+1: I will try experimenting with your code.

Me neither, and I've seen TFTP used more commonly in embedded systems. Any idea if the U-Blox module supports TFTP?

I am trying to use FTPClient library example with DLP Test (https://dlptest.com/ftp-test/) public FTP server, but its always giving me “Couldn’t connect to ftp host” error!

I haven't used that library. This is the code I was referring to:

I know you haven’t used FTPClient library in your example. I thought you might have worked with it sometime earlier.

I have successfully used ParticleFtpClient

You may need to allow for some extra delays between the individual steps of the connection setup and transfer.
I had to set a 60 second timeout for ftp.open() and at least 10ms between each following command when targeting a Linode based FTP server of mine.

2 Likes

Neither is the internet -- the ISC is trying to get rid of the protocol :slight_smile:

Between the security issues, firewall issues, and insane overhead problems...I am shocked it has been used for as long as it has. Even openbsd removed their ftp mirror :slight_smile:

1 Like