Transfering SD card data to a remote server over GPRS network

Hello all, I've been trying to send data in the form of a text file stored in my SD card to my laptop over the GPRS network via a FTP server. I've been hitting dead ends and can't find a way to do it. I'm using an Arduino MEGA, with a SIM900A GSM.

It doesn't necessarily have to be FTP. It just has to be on my computer.

1 Like

There are 2 stages to this

  1. Getting the arduino to load the SD card data onto the remote FTP server.
  2. Collecting the data from the remote FTP server using your laptop.

If your are stuck on stage 1, look at the following forum entry:
http://forum.arduino.cc/index.php?topic=178607.0

Been there, I couldn't figure what epiphany the OP had there, because I still got the same error he got.

I edited out the cftp commands and appended his code, but I couldn't get past the SD card initialisation, and the file being read.

Thanks for the reply, btw.

Generalno1:
Been there, I couldn't figure what epiphany the OP had there, because I still got the same error he got.

I edited out the cftp commands and appended his code, but I couldn't get past the SD card initialisation, and the file being read.

Thanks for the reply, btw.

If you can't even successfully open the required file on the SD card, then you have a much more basic problem than uploading the file to an FTP server.

If you post your code, someone may be able to help.

I meant that the SD card was initialised and the file was ready. It was the actual transfer that I had the issue.

As for the code, I just used the code from that thread. I also used this:
http://dostmuhammad.com/ftp-file-download-sim900/

But I got errors in that one too. Specifically, the at commands.

The commands and error messages are listed here:
http://www.cooking-hacks.com/skin/frontend/default/cooking/pdf/SIM900_AT_Command_Manual.pdf

Post the code and error messages here. Someone here may be able to help.

Alright, here you go:

The first code i used was the one mentioned previously:

#include <SD.h>

const int chipSelect = 4;
int8_t answer;
int onModulePin= 2;

char aux_str[50];

char file_name[ ]="datalog.txt";

void setup(){
  delay(5000);
    // SD function
    Serial.begin(9600);
    pinMode(chipSelect, OUTPUT);
    pinMode(10, OUTPUT);  // SD library to work
    digitalWrite(10,HIGH);
    Serial.print("Initializing SD card...");
    if (!SD.begin(chipSelect)) 
    {
    Serial.println("Card failed, or not present");
    return;
    }
    Serial.println("card initialized.");
    File dataFile = SD.open("datalog.txt", FILE_READ);
    if (dataFile)
      Serial.println(" datalog.txt is opened in read mode.");
    // GSM function
    pinMode(onModulePin, OUTPUT); 
    Serial1.begin(9600); 
    delay(3000);
    
    sendATcommand("AT", "OK", 5000);
    Serial.println("GSM modem working!");
    delay(3000);
    
    // waits for signal
    while( (sendATcommand("AT+CREG?", "+CREG: 0,1", 500) || 
            sendATcommand("AT+CREG?", "+CREG: 0,5", 500)) == 0 );
    
    // sets APN, user name and password
    sendATcommand("AT+CGSOCKCONT=1,\"IP\",\"airtelgprs.com\"", "OK", 2000);
    // ther is no username and password for my GPRS connection so I commented out this line
    //sendATcommand("AT+CSOCKAUTH=1,1,\"\",\"\"", "OK", 2000);
    
    // sets the paremeters for the FTP server
    sendATcommand("AT+CFTPSERV=\"mydomain.in\"", "OK", 2000);
    sendATcommand("AT+CFTPPORT=21", "OK", 2000);
    sendATcommand("AT+CFTPMODE=1", "OK", 2000);
    sendATcommand("AT+CFTPUN=\"username\"", "OK", 2000);
    sendATcommand("AT+CFTPPW=\"password\"", "OK", 2000);
    
    // the file must be in the current directory
    sprintf(aux_str, "AT+CFTPPUTFILE=\"%s\",0", file_name);
    answer = sendATcommand(aux_str, "+CFTPPUTFILE: 0", 60000);
    
    if (answer == 1)
    {        
        Serial.println("Upload done");    
    }
    else
    {
        Serial.println("Upload fail");    
    }
   

}
void loop(){
    
    

}

void power_on(){

    uint8_t answer=0;
    
    // checks if the module is started
    answer = sendATcommand("AT", "OK", 2000);
    if (answer == 0)
    {
        // power on pulse
        digitalWrite(onModulePin,HIGH);
        delay(3000);
        digitalWrite(onModulePin,LOW);
    
        // waits for an answer from the module
        while(answer == 0){    
            // Send AT every two seconds and wait for the answer
            answer = sendATcommand("AT", "OK", 2000);    
        }
    }
    
}


unsigned char sendATcommand(char* ATcommand, char* expected_answer1, unsigned int timeout)
{

    unsigned char x=0,  answer=0;
    char response[100];
    unsigned long previous;

    memset(response, '\0', 100);    // Initialize the string

    delay(100);

    while( Serial1.available() > 0) Serial1.read();    // Clean the input buffer

    Serial1.println(ATcommand);    // Send the AT command 


        x = 0;
    previous = millis();

    // this loop waits for the answer
    do{

        if(Serial1.available() != 0){    
            response[x] = Serial1.read();
            x++;
            // check if the desired answer is in the response of the module
            if (strstr(response, expected_answer1) != NULL)    
            {
                answer = 1;
            }
        }
        // Waits for the asnwer with time out
    }
    while((answer == 0) && ((millis() - previous) < timeout));    

    return answer;
}

I got the same error as the OP in that post. I also couldn't understand the fix he recieved later in the thread.

The other one is this :

int8_t answer;
int onModulePin = 2;
char aux_str[30];

char incoming_data[120];

char test_str[ ]= "0000000011111111222222223333333344444444555555556666666677777777000000001111111122222222333333334444";

int data_size, aux;


void setup(){

    pinMode(onModulePin, OUTPUT);
    Serial.begin(115200);


    Serial.println("Starting...");
    power_on();

    delay(5000);

    Serial.println("Connecting to the network...");

    while( (sendATcommand("AT+CREG?", "+CREG: 0,1", 500)
            || sendATcommand("AT+CREG?", "+CREG: 0,5", 500)) == 0 );

    configure_FTP();

    uploadFTP();

    downloadFTP();

    Serial.print("Incoming data: ");
    Serial.println(incoming_data);
}


void loop(){

}


void configure_FTP(){

    sendATcommand("AT+SAPBR=3,1,"Contype","GPRS"", "OK", 2000);
    sendATcommand("AT+SAPBR=3,1,"APN","APN"", "OK", 2000);
    sendATcommand("AT+SAPBR=3,1,"USER","user_name"", "OK", 2000);
    sendATcommand("AT+SAPBR=3,1,"PWD","password"", "OK", 2000);

    while (sendATcommand("AT+SAPBR=1,1", "OK", 20000) != 1);
    sendATcommand("AT+FTPCID=1", "OK", 2000);
    sendATcommand("AT+FTPSERV="ftp.yourserver.com"", "OK", 2000);
    sendATcommand("AT+FTPPORT=21", "OK", 2000);
    sendATcommand("AT+FTPUN="user_name"", "OK", 2000);
    sendATcommand("AT+FTPPW="password"", "OK", 2000);

}


void uploadFTP(){

    sendATcommand("AT+FTPPUTNAME="file_name"", "OK", 2000);
    sendATcommand("AT+FTPPUTPATH="/path"", "OK", 2000);
    if (sendATcommand("AT+FTPPUT=1", "+FTPPUT:1,1,", 30000) == 1)
    {
        data_size = 0;
        while(Serial.available()==0);
        aux = Serial.read();
        do{
            data_size *= 10;
            data_size += (aux-0x30);
            while(Serial.available()==0);
            aux = Serial.read();
        }
        while(aux != 0x0D);

        if (data_size >= 100)
        {
            if (sendATcommand("AT+FTPPUT=2,100", "+FTPPUT:2,100", 30000) == 1)
            {
                Serial.println(sendATcommand(test_str, "+FTPPUT:1,1", 30000), DEC);
                Serial.println(sendATcommand("AT+FTPPUT=2,0", "+FTPPUT:1,0", 30000), DEC);
                Serial.println("Upload done!!");
            }
            else
            {
                sendATcommand("AT+FTPPUT=2,0", "OK", 30000);
            }
        }
        else
        {
            sendATcommand("AT+FTPPUT=2,0", "OK", 30000);
        }
    }
    else
    {
        Serial.println("Error openning the FTP session");
    }
}

void downloadFTP(){

    int x = 0;

    sendATcommand("AT+FTPGETNAME="file_name"", "OK", 2000);
    sendATcommand("AT+FTPGETPATH="/path"", "OK", 2000);
    if (sendATcommand("AT+FTPGET=1 ", "+FTPGET:1,1", 30000) == 1)
    {
        do{
            if (sendATcommand2("AT+FTPGET=2,50", "+FTPGET:2,", "+FTPGET:1,", 30000) == 1)
            {
                data_size = 0;
                while(Serial.available()==0);
                aux = Serial.read();
                do{
                    data_size *= 10;
                    data_size += (aux-0x30);
                    while(Serial.available()==0);
                    aux = Serial.read();
                }while(aux != 0x0D);

                Serial.print("Data received: ");
                Serial.println(data_size);

                if (data_size > 0)
                {
                    while(Serial.available() < data_size);
                    Serial.read();

                    for (int y = 0; y < data_size; y++)
                    {
                        incoming_data[x] = Serial.read();
                        x++;
                    }
                    incoming_data[x] = '';
                }
                else
                {
                    Serial.println("Download finished");
                }
            }
            else if (answer == 2)
            {
                Serial.println("Error from FTP");
            }
            else
            {
                Serial.println("Error getting the file");
                data_size = 0;
            }
        }while (data_size > 0);
    }
    else
    {
        Serial.println("Error openning the FTP session");
    }
}




void power_on(){

    uint8_t answer=0;

    // checks if the module is started
    answer = sendATcommand("AT", "OK", 2000);
    if (answer == 0)
    {
        digitalWrite(onModulePin,HIGH);
        delay(3000);
        digitalWrite(onModulePin,LOW);

        while(answer == 0){     // Send AT every two seconds and wait for the answer
            answer = sendATcommand("AT", "OK", 2000);
        }
    }
}


int8_t sendATcommand(char* ATcommand, char* expected_answer, unsigned int timeout){

    uint8_t x=0,  answer=0;
    char response[100];
    unsigned long previous;

    memset(response, '', 100);    // Initialize the string

    delay(100);

    while( Serial.available() > 0) Serial.read();    // Clean the input buffer

    Serial.println(ATcommand);    // Send the AT command


        x = 0;
    previous = millis();

    // this loop waits for the answer
    do{
        if(Serial.available() != 0){
            // if there are data in the UART input buffer, reads it and checks for the asnwer
            response[x] = Serial.read();
            //Serial.print(response[x]);
            x++;
            // check if the desired answer  is in the response of the module
            if (strstr(response, expected_answer) != NULL)
            {
                answer = 1;
            }
        }
    }
    // Waits for the asnwer with time out
    while((answer == 0) && ((millis() - previous) < timeout));

        return answer;
}

int8_t sendATcommand2(char* ATcommand, char* expected_answer1,
            char* expected_answer2, unsigned int timeout){

    uint8_t x=0,  answer=0;
    char response[100];
    unsigned long previous;

    memset(response, '', 100);    // Initialize the string

    delay(100);

    while( Serial.available() > 0) Serial.read();    // Clean the input buffer

    Serial.println(ATcommand);    // Send the AT command


        x = 0;
    previous = millis();

    // this loop waits for the answer
    do{
        // if there are data in the UART input buffer, reads it and checks for the asnwer
        if(Serial.available() != 0){
            response[x] = Serial.read();
            x++;
            // check if the desired answer 1 is in the response of the module
            if (strstr(response, expected_answer1) != NULL)
            {
                answer = 1;
            }
            // check if the desired answer 2 is in the response of the module
            if (strstr(response, expected_answer2) != NULL)
            {
                answer = 2;
            }
        }
        // Waits for the asnwer with time out
    }while((answer == 0) && ((millis() - previous) < timeout));

        return answer;
}

I get an error in the GPRS config line, about the number of ")" in the line.

Well, the first obvious problem with the first sketch is that you are using commands like CFTPSERV which don't exist for your device SIM900A According to the earlier link for v1.05 of the user manual.

The solution was to modify the code to use commands which do exist. These are a little bit harder to use because, for example, with FTPPUT you have to manage sending a file in smaller pieces.

In your second sketch, you have commands like:

sendATcommand("AT+SAPBR=3,1,"Contype","GPRS"", "OK", 2000);

which looks like the author assumed that nested double quotes are OK in C++.
Did you get this code by following one of the links posted ?

The second was just the result of some googling.
Could you please tell me exactly how the modifications get implemented with reference to the first code I put up? Because i'm assuming it's more than just a few changes in syntax.
Thanks for the help.

#include <SD.h>

const int chipSelect = 4;
int8_t answer;
int data_size=0;
int onModulePin= 2;
int aux;
int seconds=0;
int GsmDo=0;
int GPRS_IDLE_TIME=0;
char aux_str[50];
int GsmStatut=0;

char file_name[ ]="datalog.txt";

void setup(){
  delay(5000);
    // SD function
    // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  Serial.print("Initializing SD card...");
  // On the Ethernet Shield, CS is pin 4. It's set as an output by default.
  // Note that even if it's not used as the CS pin, the hardware SS pin 
  // (10 on most Arduino boards, 53 on the Mega) must be left as an output 
  // or the SD library functions will not work. 
   pinMode(53, OUTPUT);
   
  if (!SD.begin(53)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
    File myFile = SD.open("test.txt", FILE_READ);
    if (myFile)
      Serial.println("test.txt is opened in read mode.");
    // GSM function
    pinMode(onModulePin, OUTPUT); 
    Serial1.begin(9600); 
    delay(3000);
    
    sendATcommand("AT", "OK", 5000);
    Serial.println("GSM modem working!");
    delay(3000);
    
    sendATcommand("AT+CIPCSGP=1,\"airtelgprs.com\"", "OK", 2000);
    
    sendATcommand("AT+FTPSERV=\"\"192.168.1.223", "OK", 2000);
    sendATcommand("AT+FTPPORT=21", "OK", 2000);
    sendATcommand("AT+FTPMODE=1", "OK", 2000);
    sendATcommand("AT+FTPUN=\"user\"", "OK", 2000);
    sendATcommand("AT+FTPPW=\"password\"", "OK", 2000);
    
    // waits for signal
  if (sendATcommand("AT+FTPPUT=1", "+FTPPUT:1,1,", 30000) == 1)
            {
                data_size = 0;
                while(Serial1.available()==0);
                aux = Serial1.read();
                do{
                    data_size *= 10;
                    data_size += (aux-0x30);
                    while(Serial1.available()==0);
                    aux = Serial1.read();        
                }while(aux != 0x0D);
                myFile = SD.open("TEST.TXT");
                String XcomA = "";
                String XcomB = "";
                // archivosize += 1;
                XcomA.concat("AT+FTPPUT=2,");
                XcomA.concat(data_size); 
                XcomA.concat("\"");
        
                XcomB.concat("+FTPPUT:2,");
                XcomB.concat(data_size);
                XcomB.concat("\"");
        
                char XxcomA[XcomA.length()], XxcomB[XcomB.length()];
        
                XcomA.toCharArray(XxcomA,XcomA.length());
                XcomB.toCharArray(XxcomB,XcomB.length());
        
                if (myFile) {
                    int archivosize = myFile.size();
                    while(myFile.available()){
                        //Serial.println(archivosize);
                        
                        while(archivosize >= data_size){
                            if (sendATcommand(XxcomA,XxcomB,3000) == 1){
                            for(int d = 0; d < data_size; d++){
                                Serial1.write(myFile.read());
                                archivosize -= 1;
                                //Serial.print("Archive size : ");
                                //Serial.println(archivosize);
                                }
                            }
                        }
               // Serial.print("il reste : ");
                                //Serial.println(archivosize);
                        String ScomA = "";
                        String ScomB = "";
                        ScomA.concat("AT+FTPPUT=2,");
                        ScomA.concat(archivosize); 
                        ScomA.concat("\"");
                
                        ScomB.concat("+FTPPUT:2,");
                        ScomB.concat(archivosize);
                        ScomB.concat("\"");
                
                        char CcomA[ScomA.length()], CcomB[ScomB.length()];
                
                        ScomA.toCharArray(CcomA,ScomA.length());
                        ScomB.toCharArray(CcomB,ScomB.length());
                        
                        if (sendATcommand(CcomA,CcomB,3000) == 1){
                        for(int t = 0; t < archivosize; t++){
                            Serial1.write(myFile.read());
                        //Serial.print("Archive size : ");
                        //Serial.println(t);
                        }
                        }
                    } 
                      // close the file:
                      myFile.close();
                    }
                    delay(500);
                    if (sendATcommand("AT+FTPPUT=2,0", "+FTPPUT:1,0", 30000)==1){
                        GPRS_IDLE_TIME = seconds + 10;         
                        GsmDo = 3;
                        GsmStatut = 1;
                    } 
                
                }else{
                //Erreur

}}
void loop(){
    
    

}

void power_on(){

    uint8_t answer=0;
    
    // checks if the module is started
    answer = sendATcommand("AT", "OK", 2000);
    if (answer == 0)
    {
        // power on pulse
        digitalWrite(onModulePin,HIGH);
        delay(3000);
        digitalWrite(onModulePin,LOW);
    
        // waits for an answer from the module
        while(answer == 0){    
            // Send AT every two seconds and wait for the answer
            answer = sendATcommand("AT", "OK", 2000);    
        }
    }
    
}


unsigned char sendATcommand(char* ATcommand, char* expected_answer1, unsigned int timeout)
{

    unsigned char x=0,  answer=0;
    char response[100];
    unsigned long previous;

    memset(response, '\0', 100);    // Initialize the string

    delay(100);

    while( Serial1.available() > 0) Serial1.read();    // Clean the input buffer

    Serial1.println(ATcommand);    // Send the AT command 


        x = 0;
    previous = millis();

    // this loop waits for the answer
    do{

        if(Serial1.available() != 0){    
            response[x] = Serial1.read();
            x++;
            // check if the desired answer is in the response of the module
            if (strstr(response, expected_answer1) != NULL)    
            {
                answer = 1;
            }
        }
        // Waits for the asnwer with time out
    }
    while((answer == 0) && ((millis() - previous) < timeout));    

    return answer;
}

Well I changed the code to match the SIM900's syntax. But still no transfer. This is what I got:

Initializing SD card...initialization done.
test.txt is opened in read mode.
GSM modem working!

And that's it. The GSM module is recieving.

Hi Generalno1,

Any prograss on this problem?
Im starting to look into the same topic to transfeer a file/picture from SD card to FTP server.

Hello,
I ve got same problem too.
It is OK (OK on FTP file with all data) when i put String with Serial.print,
but when i try with Sim900.write(SD.read), there is a problem!
-> Serial.write(SD.read) is good
-> Sim900.write(Serial.read) is good
-> Sim900.write(SD.read) is false

? Is someone have solution?

Here is code:

 myFile = SD.open("17211.csv",FILE_READ);

 sendATcommand( "AT+FTPPUTNAME=\"17211.csv\"","OK",2000);

 
  
 sendATcommand("AT+FTPPUTPATH=\"/\"", "OK", 2000);
 sendATcommand("AT+FTPPUT=1", "+FTPPUT:1,1,", 30000);
 

 sendATcommand("AT+FTPPUT=2,100","AT+FTPPUT=2,100",30000);
 
 Sim900Serial.print("Heures;IT1V;IH1V;IA1V;ET1V;EH1V;EA1V;OT1V;OP1V;\n1118;000;000;000;000;000;000;000;001;\n1118;000;000;000;000;000;000;000;001;\n1121;000;000;000;000;000;000;000;001;\n1125;000;000;000;000;000;000;000;001;\n1171;000;000;000;000;000;000;000;001;\n1190;000;000;000;000;000;000;000;001;\n1190;000;000;000;000;000;000;000;001;\n1191;000;000;000;000;000;000;000;001;\n1193;000;000;000;000;000;000;000;001;\n1198;000;000;000;000;000;000;000;001;\n"); 
 Serial.print("Heures;IT1V;IH1V;IA1V;ET1V;EH1V;EA1V;OT1V;OP1V;\n1118;000;000;000;000;000;000;000;001;\n1118;000;000;000;000;000;000;000;001;\n1121;000;000;000;000;000;000;000;001;\n1125;000;000;000;000;000;000;000;001;\n1171;000;000;000;000;000;000;000;001;\n1190;000;000;000;000;000;000;000;001;\n1190;000;000;000;000;000;000;000;001;\n1191;000;000;000;000;000;000;000;001;\n1193;000;000;000;000;000;000;000;001;\n1198;000;000;000;000;000;000;000;001;\n"); 
 Sim900Serial.print("\0");

 delay(5000);
 
 sendATcommand("AT+FTPPUT=2,0", "OK", 30000);
 sendATcommand("AT+FTPPUT=1,0", "OK", 30000);
 sendATcommand("AT+FTPPUT=0,1", "OK", 30000);

I have forget delay in the code with SD

delay(1000);
 while(!Sim900Serial.available());
 Serial.println("\nSim900");
 while(Sim900Serial.available()){
    Serial.write(Sim900Serial.read());}
 Serial.println("\n-------------");  
 delay(5000);
 if (myFile){
    int i=0;
    Serial.println(Nom);
    // read from the file until there's nothing else in it:
    while (i<101){
       InChar = myFile.read();
       i++;
       Sim900Serial.write(InChar);
       Serial.write(InChar);}
       Sim900Serial.print("\0");
       Delay(5000);//<------------------------------------------------------Here!
   // close the file:
    Serial.print("Compteur de bits = ");Serial.println(i);
    sendATcommand("AT+FTPPUT=2,0", "OK", 10000);
    sendATcommand("AT+FTPPUT=1,0", "OK", 10000);
    sendATcommand("AT+FTPPUT=0,1", "OK", 30000);
    myFile.close();}
 else{// if the file didn't open, print an error:
    Serial.print(F("\nError opening "));Serial.print(Nom);}

So don't forget delay!!