user56560: I've been unable to FTP anything using an Arduino and SIM800L. I have reduced the code as far as possible:
#include <SoftwareSerial.h>

//Create software serial object to communicate with SIM800L
SoftwareSerial mySerial(3, 2); //SIM800L Tx & Rx is connected to Arduino #3 & #2

String moduleAnswer = "";

void setup()
{
  //Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
  Serial.begin(9600);

  //Begin serial communication with Arduino and SIM800L
  mySerial.begin(9600);

  Serial.println("Initializing...");
  delay(1000);

  SoftwareATCommand("AT"); //Once the handshake test is successful, it will back to OK
  SoftwareATCommand("AT+CSQ"); //Signal quality test, value range is 0-31 , 31 is the best
  SoftwareATCommand("AT+CCID"); //Read SIM information to confirm whether the SIM is plugged
  SoftwareATCommand("AT+CREG?"); //Check whether it has registered in the network

  //APN and GRPS Setup
   SoftwareATCommand("AT+SAPBR=0,1"); //Close GPRS before connecting
   SoftwareATCommand("AT+SAPBR=3,1,\"Contype\",\"GPRS\""); //Configure bearer profile

  SoftwareATCommand("AT+SAPBR=1,1"); //Connect to GPRS

  //FTP Connection
  SoftwareATCommand("AT+FTPCID=1"); 
  SoftwareATCommand("AT+FTPSERV=127.189.249.205"); //Not real IP
  SoftwareATCommand("AT+FTPPORT=21"); 
  SoftwareATCommand("AT+FTPUN=user"); 
  SoftwareATCommand("AT+FTPPW=pass");

  //FTP Upload
  uploadFTP();

 }

void loop()
{
}


void uploadFTP()
{
  SoftwareATCommand("AT+FTPPUTNAME=\"test.txt\""); //Filename
  SoftwareATCommand("AT+FTPPUTPATH=/home/arduino/SolarDataLogger/"); //Path
  SoftwareATCommand("AT+FTPPUT=1"); //Start FTP
  delay(10000);
  SoftwareATCommand("AT+FTPPUT=2,100"); //Send 100 bytes of data
  delay(10000);
  SoftwareATCommand("Hello12345"); //Send Data
  SoftwareATCommand("AT+FTPPUT=2,0"); //Close FTP

}

String SoftwareATCommand(String strAT)
{

  String strNotice = "Sending: " + strAT;
  Serial.println(strNotice);
  mySerial.println(strAT);

  delay(500);
  moduleAnswer = "No Response";


  while(mySerial.available()) 
  {
    moduleAnswer = mySerial.readString();

    char* buf = (char*) malloc(sizeof(char)*moduleAnswer.length()+1);
    moduleAnswer.toCharArray(buf, moduleAnswer.length()+1);
    Serial.write(buf);//Forward what Software Serial received to Serial Port 
     - Module answer sent to screen
    free(buf);
   }

   return moduleAnswer;
}

The serial output where the trouble is:

I've tried waiting longer for the +FTPPUT: 1,1,1360 response or sending something twice, but nothing seems to work. The file gets created but no other data is ever sent.

user60381: what I observed in your code-I think you did not follow the proper sequence of connecting the GPRS context mentioned in the sim800l datasheet.
Please follow the section 3.1. bearer configuration. I also attached the screenshot herewith. So you missed setting the Access Point Name(APN). After you query the GPRS context(last step in the image), if you get the proper IP address, then you are sure to send the data over FTP. Please follow the FTP sequence mentioned in the datasheet.


user36796: Maybe its too late to respond but the line +FTPPUT: 1,65 indicates a server error.
https://www.elecrow.com/wiki/images/2/20/SIM800_Series_AT_Command_Manual_V1.09.pdf - page 275.
Please check a sequence of commands , maybe something is missing ?
I use the following sequence :
"AT+CREG?"
"AT+SAPBR=3,1,\"Contype\",\"GPRS\""
"AT+SAPBR=3,1,\"APN\",\"NAME OF YOUR PROVIDER \""
"AT+SAPBR=1,1"
"AT+SAPBR=2,1"
"AT+FTPCID=1"
"AT+FTPSERV=\"SERVER ADDRESS\""
"AT+FTPPORT=21"
"AT+FTPTYPE=\"I\""
"AT+FTPUN=\"USERNAME\""
"AT+FTPPW=\"PASSWORD\""
"AT+FTPPUTNAME=\"" + NAME OF FILE + "\""
"AT+FTPPUT=1"
"AT+FTPPUT=2," + STRING OF BUFFER SPACE ( Get from response of FTPPUT=1 )
"AT+FTPPUT=2,0"

Look on the manual for the commands above.
Sorry about my grammar 

56560: <p>I've been unable to FTP anything using an Arduino and SIM800L. I have reduced the code as far as possible:</p>

<pre><code>#include &lt;SoftwareSerial.h&gt;

//Create software serial object to communicate with SIM800L
SoftwareSerial mySerial(3, 2); //SIM800L Tx &amp; Rx is connected to Arduino #3 &amp; #2

String moduleAnswer = "";

void setup()
{
  //Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
  Serial.begin(9600);

  //Begin serial communication with Arduino and SIM800L
  mySerial.begin(9600);

  Serial.println("Initializing...");
  delay(1000);

  SoftwareATCommand("AT"); //Once the handshake test is successful, it will back to OK
  SoftwareATCommand("AT+CSQ"); //Signal quality test, value range is 0-31 , 31 is the best
  SoftwareATCommand("AT+CCID"); //Read SIM information to confirm whether the SIM is plugged
  SoftwareATCommand("AT+CREG?"); //Check whether it has registered in the network

  //APN and GRPS Setup
   SoftwareATCommand("AT+SAPBR=0,1"); //Close GPRS before connecting
   SoftwareATCommand("AT+SAPBR=3,1,\"Contype\",\"GPRS\""); //Configure bearer profile

  SoftwareATCommand("AT+SAPBR=1,1"); //Connect to GPRS

  //FTP Connection
  SoftwareATCommand("AT+FTPCID=1"); 
  SoftwareATCommand("AT+FTPSERV=127.189.249.205"); //Not real IP
  SoftwareATCommand("AT+FTPPORT=21"); 
  SoftwareATCommand("AT+FTPUN=user"); 
  SoftwareATCommand("AT+FTPPW=pass");

  //FTP Upload
  uploadFTP();

 }

void loop()
{
}


void uploadFTP()
{
  SoftwareATCommand("AT+FTPPUTNAME=\"test.txt\""); //Filename
  SoftwareATCommand("AT+FTPPUTPATH=/home/arduino/SolarDataLogger/"); //Path
  SoftwareATCommand("AT+FTPPUT=1"); //Start FTP
  delay(10000);
  SoftwareATCommand("AT+FTPPUT=2,100"); //Send 100 bytes of data
  delay(10000);
  SoftwareATCommand("Hello12345"); //Send Data
  SoftwareATCommand("AT+FTPPUT=2,0"); //Close FTP

}

String SoftwareATCommand(String strAT)
{

  String strNotice = "Sending: " + strAT;
  Serial.println(strNotice);
  mySerial.println(strAT);

  delay(500);
  moduleAnswer = "No Response";


  while(mySerial.available()) 
  {
    moduleAnswer = mySerial.readString();

    char* buf = (char*) malloc(sizeof(char)*moduleAnswer.length()+1);
    moduleAnswer.toCharArray(buf, moduleAnswer.length()+1);
    Serial.write(buf);//Forward what Software Serial received to Serial Port 
     - Module answer sent to screen
    free(buf);
   }

   return moduleAnswer;
}
</code></pre>

<p>The serial output where the trouble is:</p>

<p><a href="https://i.stack.imgur.com/aCdMA.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/aCdMA.png" alt="Serial output"></a></p>

<p>I've tried waiting longer for the <code>+FTPPUT: 1,1,1360</code> response or sending something twice, but nothing seems to work. The file gets created but no other data is ever sent.</p>
 60381: <p>what I observed in your code-I think you did not follow the proper sequence of connecting the GPRS context mentioned in the <a href="https://cdn-shop.adafruit.com/datasheets/sim800_series_ip_application_note_v1.00.pdf" rel="nofollow noreferrer">sim800l datasheet</a>.
Please follow the section 3.1. bearer configuration. I also attached the screenshot herewith. So you missed setting the Access Point Name(APN). After you query the GPRS context(last step in the image), if you get the proper IP address, then you are sure to send the data over FTP. Please follow the FTP sequence mentioned in the datasheet.<br>
<a href="https://i.stack.imgur.com/x5aln.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/x5aln.png" alt="enter image description here"></a></p>
 36796: <p>Maybe its too late to respond but the line +FTPPUT: 1,65 indicates a server error.</p>

<p><a href="https://www.elecrow.com/wiki/images/2/20/SIM800_Series_AT_Command_Manual_V1.09.pdf" rel="nofollow noreferrer">https://www.elecrow.com/wiki/images/2/20/SIM800_Series_AT_Command_Manual_V1.09.pdf</a> - page 275.</p>

<p>Please check a sequence of commands , maybe something is missing ?</p>

<p>I use the following sequence :</p>

<pre><code>"AT+CREG?"
"AT+SAPBR=3,1,\"Contype\",\"GPRS\""
"AT+SAPBR=3,1,\"APN\",\"NAME OF YOUR PROVIDER \""
"AT+SAPBR=1,1"
"AT+SAPBR=2,1"
"AT+FTPCID=1"
"AT+FTPSERV=\"SERVER ADDRESS\""
"AT+FTPPORT=21"
"AT+FTPTYPE=\"I\""
"AT+FTPUN=\"USERNAME\""
"AT+FTPPW=\"PASSWORD\""
"AT+FTPPUTNAME=\"" + NAME OF FILE + "\""
"AT+FTPPUT=1"
"AT+FTPPUT=2," + STRING OF BUFFER SPACE ( Get from response of FTPPUT=1 )
"AT+FTPPUT=2,0"
</code></pre>

<p>Look on the manual for the commands above.</p>

<p>Sorry about my grammar </p>
