My Cart

Geolocation Tracker (GPRS + GPS) with SIM908 over Arduino and Raspberry Pi

Difficulty Level: Expert -


The new shield designed for Arduino and Raspberry Pi integrates the SIM908 module which counts with both GPRS and GPS technologies what allows to easily perform realtime tracking applications. The idea is simple: read the GPS coordinates (longitude and latitude) and send them by using a HTTP request to a web server. Then use a browser to load the PHP webpage which uses Googlemaps to show the location in realtime.

All the code including the PHP scripts and the Arduino program can be downloaded and it has been released with an open source license.

Enjoy!

Ingredients

NOTE: If you are looking for a complete solution to use 3G, GPRS and A-GPS, you can use our 3G/GPRS shield for Arduino (3G + GPRS) or our Kit with Audio/Video

NOTE: The codes of the tutorial have developed to work on Arduino IDE v1.0.1

Step 1: The shield (hardware)

The board (shield) we are going to use in this tutorial is the GPRS+GPS Quadband Module for Arduino (SIM908) from Cooking hacks.

The GPRS+GPS shield is fully compatible with old Arduino USB versions, Duemilanove and Mega.

NOTE: The Arduino/Raspberry Pi jumper MUST be in Arduino position. The Raspberry Pi position should be used only if the shield is connected to a Raspberry Pi. A wrong position of this jumper can damage the GPRS+GPS shield.

GPRS+GPS shield diagram (top):

GPRS+GPS shield diagram (bottom):

The LED of the shield shows the status of the GPRS+GPS module. The table below shows the meaning of the blink of the LED.

Status SIM908 behavior
Off SIM908 is not running
64ms On/ 800ms Off SIM908 not registered the network
64ms On/ 3000ms Off SIM908 registered to the network
SIM908 registered to the network PPP GPRS communication is established

Step 1b: Using the GPRS+GPS module with Raspberry Pi

The new GPRS+GPS module can be plugged to Raspberry Pi using the Raspberry Pi to Arduino shields connection bridge.

Using arduPi library lets you to program applications for controling the GPRS+GPS in a very similar way to Arduino.

The steps are the following:

1. Paste the arduino code on the template where it says: YOUR ARDUINO CODE HERE

Code:
//Include arduPi library
#include "arduPi.h"

/*********************************************************
 *  IF YOUR ARDUINO CODE HAS OTHER FUNCTIONS APART FROM  *
 *  setup() AND loop() YOU MUST DECLARE THEM HERE        *
 * *******************************************************/

/**************************
 * YOUR ARDUINO CODE HERE *
 * ************************/

int main (){
    setup();
    while(1){
        loop();
    }
    return (0);
}
    

2. Compile the file as follows:

g++ -lrt -lpthread my_program.cpp arduPi.cpp -o my_program
		

Step 2: Using GPRS+GPS module with AT commands

Important issues:

  • Use capital letters for AT commands.
  • Send CR (Carriage return) and LF (Line feed) after the AT command.
  • Place the serial communication jumpers in the right position.
  • Use an external power supply and place the power jumpers in the right position. If the shield is powered from the Arduino, the power jumper must be in Arduino 5V position. It the shield is powered from the Vin input (in the shield), the power jumper must be in Vext position.
Command Response Description
AT OK If you get OK, the communication with the module is working
AT+CPIN="****" OK If the SIM card is locked with PIN (**** is the pin number)
AT+COPS?   Operator information

Using GPRS+GPS module with AT commands in Arduino

The first thing we are going to do with the module is to connect the module to a PC directly (using an Arduino as gateway) and check the basic AT commands. In this case, serial communication jumpers have to be set on USB gateway position.

Remember take out the ATmega microcontroller from the Arduino gateway.

Connect the antennas to the shield:

Connect the shield to the Arduino gateway:

Then connect the USB cable and the SIM card.

Finally plug the USB cable to the computer and open a serial port terminal to communicate via the usb port (e.g: hyperterminal (win), cutecom / gtkterm (linux)).

If you use the Arduino IDE serial monitor for sending AT commands – Be sure that you are sending CR (Carriage return) and LF (Line Feed).

Set the baudrate to 115200 bps and open the serial port, then press the ON button for two seconds. Then if you type AT you'll get OK, this means that the communication with the module is working fine. Now, with the module working you can check some AT commands to control the module, the basic commands are:

Important type commands in capital letters and with CR (carriage return) and LF (line feed)!!!

NOTE: With some sketches, the buffer of the UART may be small, to increase the length of the buffer you need to change these lines in the file HardwareSerial.h in /arduino-1.0.X/hardware/arduino/avr/cores/arduino/ (or in file HardwareSerial.cpp in /arduino-1.0.X/hardware/arduino/cores/arduino/ depending on the Arduino IDE version)

#if (RAMEND < 1000)
#define SERIAL_TX_BUFFER_SIZE 16
#define SERIAL_RX_BUFFER_SIZE 16
#else
#define SERIAL_TX_BUFFER_SIZE 64
#define SERIAL_RX_BUFFER_SIZE 64
#endif
#endif
                

to

#if (RAMEND < 1000)
#define SERIAL_TX_BUFFER_SIZE 192
#define SERIAL_RX_BUFFER_SIZE 192
#else
#define SERIAL_TX_BUFFER_SIZE 256
#define SERIAL_RX_BUFFER_SIZE 256
#endif
#endif
                

Using GPRS+GPS module with AT commands in Raspberry Pi

The first thing we are going to do with the module is to check the basic AT commands in gateway mode. Using gateway mode, commands can be sent from our Raspberry Pi directly to any serial module. To stablish UART connection with the module you can use several programs as cutecom in Raspbian graphical environment or minicom in a terminal window in order to use it via SSH . For using minicom follow these steps:

  1. Place the Arduino/RPI jumper in the SIM908 shield to the right, in RPI position.

  2. Place the two Serial com. jumpers in the SIM908 shield to the left, in Arduino position. These jumpers always have to be in this position, in gateway mode and when you run codes.

  3. We recommend to power externally the shield, but it's not necessary in all cases.

    If you decide not to use an external power supply you must set the “Vin ext. Jumper” to the right, in “Arduino 5V position” and do not forget to place the switch in the Raspberry connection bridge to the right.

    If you choose to use an external power supply you must place it through the external power input, the “Vin ext. jumper” must be set to the left, in “Vext position” and the BAT/REG jumper must be set to the right, in REG position. The power supply must be able to provide sufficient current up to 2A. You can also use a battery to external power the shield, in that case put the BAT/REG jumper to the left, in BAT position.

    Besides this, do not forget to place the switch in the Raspberry connection bridge to the left.

    You can check our FAQ about 3G/Sim900/Sim908 here.

  4. Connect the antennas to the shield and the shield to the Raspberry Pi connection bridge. Now press the ON button in the shield, you will see a green LED.

  5. Open a Terminal window on Raspberry Pi, or connect to Raspberry Pi through SSH. In order to enter via SSH change here the IP from your Raspberry Pi. The default user is pi.
    ssh -X pi@192.168.1.X

    Now you will have to type your password. The default password is “raspberry”.

  6. Install minicom (only if you haven't done it before):
    sudo apt-get install minicom

  7. Open comunication with the module UART, the baudrate is 115200:
    minicom -b 115200 -o -D /dev/ttyAMA0

  8. Then if you type AT you'll get OK, this means that the communication with the module is working fine. Now, with the module working you can check some AT commands to control the module.

  9. To exit minicom press CTRL+A, then press X and Yes.

Step 3: Powering the board:

There are 3 methods to power the GPRS+GPS shield:

The first one is powering the shield with Arduino 5v (ICSP header). You must set the BAT/REG jumper in REG position, Vin in Ard 5v and remove the charge jumper. Some of the USB ports on computers are not able to give all the current the module needs to work, if your module goes down when it tries to connect to the network, you can use an external power supply (12V - 2A) on the Arduino.

The second one is powering the shield directly via Vext header. You must set the BAT/REG jumper in REG position, Vin in Vext and remove the charge jumper. The external power supply can be able to supply current peaks about 2A. We recommend a 12V-2A power supply.

The last one is using a one cell Li-ion battery. You must set the BAT/REG jumper in BAT position, remove the Vin jumper and set the charge jumper. The shield uses the battery to powers itself but it can't power the Arduino board. To recharge the battery with the shield you only need to power the Arduino. The shield uses the 5v (ICSP header) to charge the battery.

The next table shows a little resume:

Power source BAT/REG jumper Vin jumper Charge jumper
From Arduino Reg Ard Remove
External power Reg Vext Remove
Battery Bat Remove Keep

Step 4: Using the shield in standalone mode - Calls

Originating and receiving voice calls

The code example and the connection diagram shown below are used to originate a voice call and, pushing a button, end that voice call. The button is connected between digital pin 12 an ground. A 10kΩ pull-up resistor is needed at this pin.

Arduino code:

Code:
/*  
 *  GPRS+GPS Quadband Module (SIM908)
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  a
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           2.0
 *  Design:            David GascĂłn 
 *  Implementation:    Alejandro Gallego & Marcos Martinez
 */
 
 
int8_t answer;
int onModulePin = 2;
int button = 12;
char aux_str[30];

char phone_number[]="******";     // ********* is the number to call
char pin[] = "****";

void setup(){

    pinMode(onModulePin, OUTPUT);
    pinMode(button, INPUT);
    Serial.begin(115200);      
    
    Serial.println("Starting...");
    power_on();
    
    delay(3000);
    
    // sets the PIN code
    sprintf(aux_str, "AT+CPIN=%s", pin);
    sendATcommand(aux_str, "OK", 2000);

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

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

    sprintf(aux_str, "ATD%s;", phone_number);
    sendATcommand(aux_str, "OK", 10000);
    
    // press the button for hang the call 
    while(digitalRead(button)==1);        

    Serial.println("ATH");            // disconnects the existing call
    

}

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);    
        }
    }
    
}

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, '\0', 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();
            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;
}
                

Raspberry Pi code:

Code:
/*  
 *  GPRS+GPS Quadband Module (SIM908)
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  a
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           2.0
 *  Design:            David GascĂłn 
 *  Implementation:    Alejandro Gallego & Marcos Martinez
 */
 
 //Include arduPi library
#include "arduPi.h"

int8_t sendATcommand(const char* ATcommand, const char* expected_answer, unsigned int timeout);
void power_on();
 
int8_t answer;
int onModulePin = 2;
int button = 12;
char aux_str[30];

char phone_number[]="*******";     // ********* is the number to call
char pin[] = "*******";

void setup(){

    pinMode(onModulePin, OUTPUT);
    pinMode(button, INPUT);
    Serial.begin(115200);      
    
    Serial.println("Starting...");
    power_on();
    
    delay(3000);
    
    // sets the PIN code
    sprintf(aux_str, "AT+CPIN=%s", pin);
    sendATcommand(aux_str, "OK", 2000);
    
    delay(3000);
    
    printf("Connecting to the network...\n");

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

    sprintf(aux_str, "ATD%s;", phone_number);
    sendATcommand(aux_str, "OK", 10000);
    
    // press the button for hang the call 
    while(digitalRead(button)==1);        

    Serial.println("ATH");            // disconnects the existing call
    printf("Call disconnected\n");
    

}

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);    
        }
    }
    
}

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

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

    memset(response, '\0', 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();
            printf("%c",response[x]);
            x++;
            // check if the desired answer  is in the response of the module
            if (strstr(response, expected_answer) != NULL)    
            {
				printf("\n");
                answer = 1;
            }
        }
    }
    // Waits for the asnwer with time out
    while((answer == 0) && ((millis() - previous) < timeout));    

        return answer;
}

int main (){
    setup();
    while(1){
        loop();
    }
    return (0);
}

                

To make a lost call next code is used.

Arduino code:

Code:
/*  
 *  GPRS+GPS Quadband Module (SIM908)
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  a
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           2.0
 *  Design:            David GascĂłn 
 *  Implementation:    Alejandro Gallego & Marcos Martinez
 */
 
int8_t answer;
int onModulePin = 2;
int seconds = 20;
char aux_str[30];

char phone_number[]="*******";     // ********* is the number to call
char pin[] = "*******";

void setup(){

    pinMode(onModulePin, OUTPUT);
    Serial.begin(115200);  
    
    
    Serial.println("Starting...");
    power_on();
    
    delay(3000);
    
    // sets the PIN code
    sprintf(aux_str, "AT+CPIN=%s", pin);
    sendATcommand(aux_str, "OK", 2000);
    
    delay(3000);
    
    Serial.println("Connecting to the network...");

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

    sprintf(aux_str, "ATD%s;", phone_number);
    sendATcommand(aux_str, "OK", 10000);
   
   
    delay(seconds * 1000);

    Serial.println("ATH");            // disconnects the existing call
    Serial.println("Call disconnected");
    

}

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);    
        }
    }
    
}

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, '\0', 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  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;
}
                

Raspberry Pi code:

Code:
/*  
 *  GPRS+GPS Quadband Module (SIM908)
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  a
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           2.0
 *  Design:            David GascĂłn 
 *  Implementation:    Alejandro Gallego & Marcos Martinez
 */
 

//Include arduPi library
#include "arduPi.h"

int8_t sendATcommand(const char* ATcommand, const char* expected_answer, unsigned int timeout);
void power_on();

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

char phone_number[]="*******";     // ********* is the number to call
char pin[] = "*******";

void setup(){

    pinMode(onModulePin, OUTPUT);
    Serial.begin(115200);  
    
    
    printf("Starting...\n");
    power_on();
    
    delay(3000);
    
    // sets the PIN code
    sprintf(aux_str, "AT+CPIN=%s", pin);
    sendATcommand(aux_str, "OK", 2000);
    
    delay(3000);
    
    printf("Connecting to the network...\n");

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

    sprintf(aux_str, "ATD%s;", phone_number);
    sendATcommand(aux_str, "OK", 10000);
   
   
    delay(seconds * 1000);

    Serial.println("ATH");            // disconnects the existing call
    printf("Call disconnected\n");
    

}

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);    
        }
    }
    
}

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

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

    memset(response, '\0', 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();
            printf("%c",response[x]);
            x++;
            // check if the desired answer  is in the response of the module
            if (strstr(response, expected_answer) != NULL)    
            {
				printf("\n");
                answer = 1;
            }
        }
    }
    // Waits for the asnwer with time out
    while((answer == 0) && ((millis() - previous) < timeout));    

        return answer;
}

int main (){
    setup();
    while(1){
        loop();
    }
    return (0);
}

                

To receive calls the used code are this and the connection diagram is the same that the used to originate calls. Don't forget the pull-up resistor on pin 12.

Command summary

Command Response Description
ATD*********;   ********* is the number to call.
ATA OK Answer an incoming call.
ATH OK Cancel voice calls.

Step 5: Using the shield in standalone mode
             Sending and receiving SMS

The first code is used to send a SMS, the second one reads the first SMS into the memory.

Arduino code:

Code:
/*  
 *  GPRS+GPS Quadband Module (SIM908)
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  a
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           2.0
 *  Design:            David GascĂłn 
 *  Implementation:    Alejandro Gallego & Marcos Martinez
 */

int8_t answer;
int onModulePin= 2;
char aux_string[30];
char phone_number[]="*********";   // ********* is the number to call
char pin[] = "****";
char sms_text[]="Test-Arduino-Hello World";     

void setup(){

    pinMode(onModulePin, OUTPUT);
    Serial.begin(115200);    
        
    Serial.println("Starting...");
    power_on();
    
    delay(3000);
    
    // sets the PIN code
    sprintf(aux_string, "AT+CPIN=%s", pin);
    sendATcommand(aux_string, "OK", 2000);
    
    delay(3000);
    
    Serial.println("Connecting to the network...");

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

    Serial.print("Setting SMS mode...");
    sendATcommand("AT+CMGF=1", "OK", 1000);    // sets the SMS mode to text
    Serial.println("Sending SMS");
    
    sprintf(aux_string,"AT+CMGS=\"%s\"", phone_number);
    answer = sendATcommand(aux_string, ">", 2000);    // send the SMS number
    if (answer == 1)
    {
        Serial.println(sms_text);
        Serial.write(0x1A);
        answer = sendATcommand("", "OK", 20000);
        if (answer == 1)
        {
            Serial.print("Sent ");    
        }
        else
        {
            Serial.print("error ");
        }
    }
    else
    {
        Serial.print("error ");
        Serial.println(answer, DEC);
    }

}


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);    
        }
    }
    
}

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, '\0', 100);    // Initialice 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 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;
}
    

Raspberry Pi code:

Code:
/*  
 *  GPRS+GPS Quadband Module (SIM908)
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  a
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           2.0
 *  Design:            David GascĂłn 
 *  Implementation:    Alejandro Gallego & Marcos Martinez
 */

//Include arduPi library
#include "arduPi.h"

int8_t sendATcommand(const char* ATcommand, const char* expected_answer, unsigned int timeout);
void power_on();

int8_t answer;
int onModulePin= 2;
char aux_string[30];
char phone_number[]="*********";   // ********* is the number to call
char pin[] = "*******";
char sms_text[]="Test-Arduino-Hello World";     

void setup(){

    pinMode(onModulePin, OUTPUT);
    Serial.begin(115200);    
        
    printf("Starting...\n");
    power_on();
    
    delay(3000);
    
    // sets the PIN code
    sprintf(aux_string, "AT+CPIN=%s", pin);
    sendATcommand(aux_string, "OK", 2000);
    
    delay(3000);
    
    printf("Connecting to the network...\n");

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

    printf("Setting SMS mode...\n");
    sendATcommand("AT+CMGF=1", "OK", 1000);    // sets the SMS mode to text
    printf("Sending SMS\n");
    
    sprintf(aux_string,"AT+CMGS=\"%s\"", phone_number);
    answer = sendATcommand(aux_string, ">", 2000);    // send the SMS number
    if (answer == 1)
    {
        Serial.println(sms_text);
        Serial.write(0x1A);
        answer = sendATcommand("", "OK", 20000);
        if (answer == 1)
        {
            printf("Sent \n");    
        }
        else
        {
            printf("error \n");
        }
    }
    else
    {
        printf("error %o\n",answer);
    }

}


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);    
        }
    }
    
}

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

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

    memset(response, '\0', 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();
            printf("%c",response[x]);
            x++;
            // check if the desired answer  is in the response of the module
            if (strstr(response, expected_answer) != NULL)    
            {
				printf("\n");
                answer = 1;
            }
        }
    }
    // Waits for the asnwer with time out
    while((answer == 0) && ((millis() - previous) < timeout));    

        return answer;
}

int main (){
    setup();
    while(1){
        loop();
    }
    return (0);
}

    

Arduino code:

Code:
/*  
 *  GPRS+GPS Quadband Module (SIM908)
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  a
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           2.0
 *  Design:            David GascĂłn 
 *  Implementation:    Alejandro Gallego & Marcos Martinez
 */

int8_t answer;
int x;
int onModulePin= 2;
char aux_string[30];
char SMS[200];
char pin[] = "****";

void setup(){

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

    Serial.println("Starting...");
    power_on();
    
    delay(3000);
    
    // sets the PIN code
    sprintf(aux_string, "AT+CPIN=%s", pin);
    sendATcommand(aux_string, "OK", 2000);
    
    delay(3000);
    
    Serial.println("Setting SMS mode...");
    sendATcommand("AT+CMGF=1", "OK", 1000);    // sets the SMS mode to text
    sendATcommand("AT+CPMS=\"SM\",\"SM\",\"SM\"", "OK", 1000);    // selects the memory

    answer = sendATcommand("AT+CMGR=1", "+CMGR:", 2000);    // reads the first SMS
    if (answer == 1)
    {
        answer = 0;
        while(Serial.available() == 0);
        // this loop reads the data of the SMS
        do{
            // if there are data in the UART input buffer, reads it and checks for the asnwer
            if(Serial.available() > 0){    
                SMS[x] = Serial.read();
                x++;
                // check if the desired answer (OK) is in the response of the module
                if (strstr(SMS, "OK") != NULL)    
                {
                    answer = 1;
                }
            }
        }while(answer == 0);    // Waits for the asnwer with time out
        
        SMS[x] = '\0';
        
        Serial.print(SMS);    
        
    }
    else
    {
        Serial.print("error ");
        Serial.println(answer, DEC);
    }


}


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);    
        }
    }
    
}

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, '\0', 100);    // Initialice 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 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;
}
    

Raspberry Pi code:

Code:
/*  
 *  GPRS+GPS Quadband Module (SIM908)
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  a
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           2.0
 *  Design:            David GascĂłn 
 *  Implementation:    Alejandro Gallego & Marcos Martinez
 */


//Include arduPi library
#include "arduPi.h"

int8_t sendATcommand(const char* ATcommand, const char* expected_answer, unsigned int timeout);
void power_on();

int8_t answer;
int x;
int onModulePin= 2;
char aux_string[30];
char SMS[200];
char pin[] = "*******";


void setup(){

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

    printf("Starting...\n");
    power_on();
    
    delay(3000);
    
    // sets the PIN code
    sprintf(aux_string, "AT+CPIN=%s", pin);
    sendATcommand(aux_string, "OK", 2000);
    
    delay(3000);
    
    printf("Setting SMS mode...\n");
    sendATcommand("AT+CMGF=1", "OK", 1000);    // sets the SMS mode to text
    sendATcommand("AT+CPMS=\"SM\",\"SM\",\"SM\"", "OK", 1000);    // selects the memory

    answer = sendATcommand("AT+CMGR=1", "+CMGR:", 2000);    // reads the first SMS
    if (answer == 1)
    {
        answer = 0;
        while(Serial.available() == 0);
        // this loop reads the data of the SMS
        do{
            // if there are data in the UART input buffer, reads it and checks for the asnwer
            if(Serial.available() > 0){    
                SMS[x] = Serial.read();
                x++;
                // check if the desired answer (OK) is in the response of the module
                if (strstr(SMS, "OK") != NULL)    
                {
                    answer = 1;
                }
            }
        }while(answer == 0);    // Waits for the asnwer with time out
        
        SMS[x] = '\0';
        
        printf("%s\n",SMS);    
        
    }
    else
    {
        printf("error %o\n",answer);
    }


}


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);    
        }
    }
    
}

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

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

    memset(response, '\0', 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();
            printf("%c",response[x]);
            x++;
            // check if the desired answer  is in the response of the module
            if (strstr(response, expected_answer) != NULL)    
            {
				printf("\n");
                answer = 1;
            }
        }
    }
    // Waits for the asnwer with time out
    while((answer == 0) && ((millis() - previous) < timeout));    

        return answer;
}

int main (){
    setup();
    while(1){
        loop();
    }
    return (0);
}

    

Command summary

Command Response Description
AT+CMGF= OK Specifies the input and output format of the short messages. 0 for PDU mode and 1 for text mode.
AT+CMGS   Sends a message.
AT+CMGR=*   Reads a message. * is the number of the message.

Step 6: Using the shield in standalone mode - FTP

Creating a file into the FTP server, writing it and reading it.

Arduino code:

Code:
/*  
 *  GPRS+GPS Quadband Module (SIM908)
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  a
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           2.0
 *  Design:            David GascĂłn 
 *  Implementation:    Alejandro Gallego & Marcos Martinez
 */


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

char pin[]="*******";
char apn[]="*******";
char user_name[]="*******";
char password[]="*******";
char ftp_server[]="*******";
char ftp_user_name[]="*******";
char ftp_password[]="*******";
char path[]="/*******/";

char incoming_data[120];

char file_name[ ]="test.txt";
char test_str[ ]= "0000000011111111222222223333333344444444555555556666666677777777000000001111111122222222333333334444";

int data_size, aux;


void setup(){

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


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

    delay(5000);
    
    //sets the PIN code
    snprintf(aux_str, sizeof(aux_str), "AT+CPIN=%s", pin);
    sendATcommand(aux_str, "OK", 2000);

    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(){
  
    // sets APN, user name and password
    sendATcommand("AT+SAPBR=3,1,\"Contype\",\"GPRS\"", "OK", 2000);
    snprintf(aux_str, sizeof(aux_str), "AT+SAPBR=3,1,\"APN\",\"%s\"", apn);
    sendATcommand(aux_str, "OK", 2000);
    
    snprintf(aux_str, sizeof(aux_str), "AT+SAPBR=3,1,\"USER\",\"%s\"", user_name);
    sendATcommand(aux_str, "OK", 2000);
    
    snprintf(aux_str, sizeof(aux_str), "AT+SAPBR=3,1,\"PWD\",\"%s\"", password);
    sendATcommand(aux_str, "OK", 2000);
  
    // sets the paremeters for the FTP server
    while (sendATcommand("AT+SAPBR=1,1", "OK", 20000) != 1);
    sendATcommand("AT+FTPCID=1", "OK", 2000);
    snprintf(aux_str, sizeof(aux_str), "AT+FTPSERV=\"%s\"", ftp_server);
    sendATcommand(aux_str, "OK", 2000);
    sendATcommand("AT+FTPPORT=21", "OK", 2000);
    snprintf(aux_str, sizeof(aux_str), "AT+FTPUN=\"%s\"", ftp_user_name);
    sendATcommand(aux_str, "OK", 2000);
    snprintf(aux_str, sizeof(aux_str), "AT+FTPPW=\"%s\"", ftp_password);
    sendATcommand(aux_str, "OK", 2000);
    
    
    
}


void uploadFTP(){
    
    snprintf(aux_str, sizeof(aux_str), "AT+FTPPUTNAME=\"%s\"", file_name);
    sendATcommand(aux_str, "OK", 2000);
    snprintf(aux_str, sizeof(aux_str), "AT+FTPPUTPATH=\"%s\"", path);
    sendATcommand(aux_str, "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)
            {
                sendATcommand(test_str, "+FTPPUT:1,1", 30000);          
                sendATcommand("AT+FTPPUT=2,0", "+FTPPUT:1,0", 30000);
                Serial.println("Upload done!!");
            }
            else 
            {
                sendATcommand("AT+FTPPUT=2,0", "OK", 30000);                    
            }
        }
        else
        {
            sendATcommand("AT+FTPPUT=2,0", "OK", 30000); 
        }
    }
    else
    {
        Serial.println("Error opening the FTP session");
    }
}

void downloadFTP(){

    int x = 0;
    snprintf(aux_str, sizeof(aux_str), "AT+FTPGETNAME=\"%s\"", file_name);
    sendATcommand(aux_str, "OK", 2000); 
    snprintf(aux_str, sizeof(aux_str), "AT+FTPGETPATH=\"%s\"", path);
    sendATcommand(aux_str, "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] = '\0';
                }
                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 opening 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, '\0', 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, '\0', 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;
}
    

Raspberry Pi code:

Code:
/*  
 *  GPRS+GPS Quadband Module (SIM908)
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  a
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           2.0
 *  Design:            David GascĂłn 
 *  Implementation:    Alejandro Gallego & Marcos Martinez
 */

//Include arduPi library
#include "arduPi.h"

int8_t sendATcommand2(const char* ATcommand, const char* expected_answer1, const char* expected_answer2, unsigned int timeout);
int8_t sendATcommand(const char* ATcommand, const char* expected_answer, unsigned int timeout);

void power_on();
void downloadFTP();
void uploadFTP();
void configure_FTP();

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



char pin[]="*******";
char apn[]="*******";
char user_name[]="*******";
char password[]="*******";
char ftp_server[]="*******";
char ftp_user_name[]="*******";
char ftp_password[]="*******";
char path[]="/*******/";

char incoming_data[120];


char file_name[ ]="test.txt";
char test_str[ ]= "0000000011111111222222223333333344444444555555556666666677777777000000001111111122222222333333334444";

int data_size, aux;


void setup(){

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


    printf("Starting...\n");
    power_on();

    delay(5000);

    //sets the PIN code
    snprintf(aux_str, sizeof(aux_str), "AT+CPIN=%s", pin);
    sendATcommand(aux_str, "OK", 2000);

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

    configure_FTP();

    uploadFTP();

    downloadFTP();

    printf("Incoming data: %s\n",incoming_data);

}


void loop(){

}


void configure_FTP(){

    // sets APN, user name and password
    sendATcommand("AT+SAPBR=3,1,\"Contype\",\"GPRS\"", "OK", 2000);
    snprintf(aux_str, sizeof(aux_str), "AT+SAPBR=3,1,\"APN\",\"%s\"", apn);
    sendATcommand(aux_str, "OK", 2000);
    
    snprintf(aux_str, sizeof(aux_str), "AT+SAPBR=3,1,\"USER\",\"%s\"", user_name);
    sendATcommand(aux_str, "OK", 2000);
    
    snprintf(aux_str, sizeof(aux_str), "AT+SAPBR=3,1,\"PWD\",\"%s\"", password);
    sendATcommand(aux_str, "OK", 2000);
  
    // sets the paremeters for the FTP server
    while (sendATcommand("AT+SAPBR=1,1", "OK", 20000) != 1);
    sendATcommand("AT+FTPCID=1", "OK", 2000);
    snprintf(aux_str, sizeof(aux_str), "AT+FTPSERV=\"%s\"", ftp_server);
    sendATcommand(aux_str, "OK", 2000);
    sendATcommand("AT+FTPPORT=21", "OK", 2000);
    snprintf(aux_str, sizeof(aux_str), "AT+FTPUN=\"%s\"", ftp_user_name);
    sendATcommand(aux_str, "OK", 2000);
    snprintf(aux_str, sizeof(aux_str), "AT+FTPPW=\"%s\"", ftp_password);
    sendATcommand(aux_str, "OK", 2000);

}


void uploadFTP(){

    snprintf(aux_str, sizeof(aux_str), "AT+FTPPUTNAME=\"%s\"", file_name);
    sendATcommand(aux_str, "OK", 2000);
    snprintf(aux_str, sizeof(aux_str), "AT+FTPPUTPATH=\"%s\"", path);
    sendATcommand(aux_str, "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)
            {
                sendATcommand(test_str, "+FTPPUT:1,1", 30000);          
                sendATcommand("AT+FTPPUT=2,0", "+FTPPUT:1,0", 30000);
                printf("Upload done!!\n");
            }
            else 
            {
                sendATcommand("AT+FTPPUT=2,0", "OK", 30000);                    
            }
        }
        else
        {
            sendATcommand("AT+FTPPUT=2,0", "OK", 30000); 
        }
    }
    else
    {
        printf("Error opening the FTP session\n");
    }
}

void downloadFTP(){

    int x = 0;

    snprintf(aux_str, sizeof(aux_str), "AT+FTPGETNAME=\"%s\"", file_name);
    sendATcommand(aux_str, "OK", 2000); 
    snprintf(aux_str, sizeof(aux_str), "AT+FTPGETPATH=\"%s\"", path);
    sendATcommand(aux_str, "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);

                printf("Data received: %d\n",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] = '\0';
                }
                else
                {
                    printf("Download finished\n");    
                }
            }
            else if (answer == 2)
            {
                 printf("Error from FTP\n");
            }
            else
            {
                printf("Error getting the file\n");
                data_size = 0;
            }
        }while (data_size > 0);
    }
    else
    {
        printf("Error opening the FTP session\n");
    }
}




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(const char* ATcommand, const char* expected_answer, unsigned int timeout){

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

    memset(response, '\0', 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();
            printf("%c",response[x]);
            x++;
            // check if the desired answer  is in the response of the module
            if (strstr(response, expected_answer) != NULL)    
            {
				printf("\n");
                answer = 1;
            }
        }
    }
    // Waits for the asnwer with time out
    while((answer == 0) && ((millis() - previous) < timeout));    

        return answer;
}

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

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

    memset(response, '\0', 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();
            printf("%c",response[x]);
            x++;
            // check if the desired answer 1  is in the response of the module
            if (strstr(response, expected_answer1) != NULL)    
            {
				printf("\n");
                answer = 1;
            }
            // check if the desired answer 2 is in the response of the module
            else if (strstr(response, expected_answer2) != NULL)    
            {
				printf("\n");
                answer = 2;
            }
        }
    }
    // Waits for the asnwer with time out
    while((answer == 0) && ((millis() - previous) < timeout));    

    return answer;
}

int main (){
    setup();
    while(1){
        loop();
    }
    return (0);
}

    

Command summary

AT command Response Description
AT+SAPBR OK Configures GPRS profile.
AT+FTPCID=1 OK Selects profile 1 for FTP.
AT+FTPSERV=”****” OK Sets FTP server domain name or IP address. **** is the domain name or the IP.
AT+FTPPORT=*** OK Sets FTP server port. *** is the port.
AT+FTPUN=”***” OK Sets user name for FTP server access. *** is the user name.
AT+FTPPW=”***” OK Sets password for FTP server access. *** is the password.
AT+FTPPUTNAME="****" OK Sets destiny name for the file.*** is the name of the file.
AT+FTPPUTPATH="****" OK Sets destiny file path. *** is the path of the file.
AT+FTPPUT OK Use to put a file into the FTP server.
AT+FTPGETNAME="****" OK Sets origin name for the file.*** is the name of the file.
AT+FTPGETPATH="****" OK Sets origin file path. *** is the path of the file.
AT+FTPGET   Use to get a file into the FTP server.

Step 7: Using the shield in standalone mode - TCP and UDP

Single client

Sending data to a TCP server first, and then it sends to a UDP server.

Arduino code:

Code:
/*  
 *  GPRS+GPS Quadband Module (SIM908)
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  a
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           2.0
 *  Design:            David GascĂłn 
 *  Implementation:    Alejandro Gallego & Marcos Martinez
 */

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

char pin[]="*******";
char apn[]="*******";
char user_name[]="*******";
char password[]="*******";
char IP_address[]="*******";
char port[]="*******";

char ip_data[40]="Test string from GPRS shield\r\n";



void setup(){

    pinMode(onModulePin, OUTPUT);
    Serial.begin(115200);    
    
    Serial.println("Starting...");
    power_on();
    
    delay(3000);
    
    //sets the PIN code
    snprintf(aux_str, sizeof(aux_str), "AT+CPIN=%s", pin);
    sendATcommand(aux_str, "OK", 2000);
    
    delay(3000);
    
    Serial.println("Connecting to the network...");

    while( sendATcommand2("AT+CREG?", "+CREG: 0,1", "+CREG: 0,5", 1000)== 0 );

}


void loop(){
    
 
    // Selects Single-connection mode
    if (sendATcommand2("AT+CIPMUX=0", "OK", "ERROR", 1000) == 1)
    {
        // Waits for status IP INITIAL
        while(sendATcommand("AT+CIPSTATUS", "INITIAL", 500)  == 0 );
        delay(5000);
        
        snprintf(aux_str, sizeof(aux_str), "AT+CSTT=\"%s\",\"%s\",\"%s\"", apn, user_name, password);
         
        // Sets the APN, user name and password
        if (sendATcommand2(aux_str, "OK",  "ERROR", 30000) == 1)
        {            
            // Waits for status IP START
            while(sendATcommand("AT+CIPSTATUS", "START", 500)  == 0 );
            delay(5000);
            
            // Brings Up Wireless Connection
            if (sendATcommand2("AT+CIICR", "OK", "ERROR", 30000) == 1)
            {
                // Waits for status IP GPRSACT
                while(sendATcommand("AT+CIPSTATUS", "GPRSACT", 500)  == 0 );
                delay(5000);
                
                // Gets Local IP Address
                if (sendATcommand2("AT+CIFSR", ".", "ERROR", 10000) == 1)
                {
                    // Waits for status IP STATUS
                    while(sendATcommand("AT+CIPSTATUS", "IP STATUS", 500)  == 0 );
                    delay(5000);
                    Serial.println("Opening TCP");
                    
                    snprintf(aux_str, sizeof(aux_str), "AT+CIPSTART=\"TCP\",\"%s\",\"%s\"", IP_address, port);
                    
                    // Opens a TCP socket
                    if (sendATcommand2(aux_str, "CONNECT OK", "CONNECT FAIL", 30000) == 1)
                    {
                        Serial.println("Connected");
                        
                        // Sends some data to the TCP socket
                        sprintf(aux_str,"AT+CIPSEND=%d", strlen(ip_data));
                        if (sendATcommand2(aux_str, ">", "ERROR", 10000) == 1)    
                        {
                            sendATcommand2(ip_data, "SEND OK", "ERROR", 10000);
                        }
                        
                        // Closes the socket
                        sendATcommand2("AT+CIPCLOSE", "CLOSE OK", "ERROR", 10000);
                    }
                    else
                    {
                        Serial.println("Error opening the connection");
                    }  
                }
                else
                {
                    Serial.println("Error getting the IP address");
                }  
            }
            else
            {
                Serial.println("Error bring up wireless connection");
            }
        }
        else
        {
            Serial.println("Error setting the APN");
        } 
    }
    else
    {
        Serial.println("Error setting the single connection");
    }
    
    sendATcommand2("AT+CIPSHUT", "OK", "ERROR", 10000);
    delay(10000);
}

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);    
        }
    }
    
}

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, '\0', 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, '\0', 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
            else if (strstr(response, expected_answer2) != NULL)    
            {
                answer = 2;
            }
        }
    }
    // Waits for the asnwer with time out
    while((answer == 0) && ((millis() - previous) < timeout));    

    return answer;
}
    

Raspberry Pi code:

Code:
/*  
 *  GPRS+GPS Quadband Module (SIM908)
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  a
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           2.0
 *  Design:            David GascĂłn 
 *  Implementation:    Alejandro Gallego & Marcos Martinez
 */

 //Include arduPi library
#include "arduPi.h"

 int8_t sendATcommand2(const char* ATcommand, const char* expected_answer1, const char* expected_answer2, unsigned int timeout);
 int8_t sendATcommand(const char* ATcommand, const char* expected_answer, unsigned int timeout);
 void power_on();


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

char pin[]="*******";
char apn[]="*******";
char user_name[]="*******";
char password[]="*******";
char IP_address[]="*******";
char port[]="*******";

char ip_data[40]="Test string from GPRS shield\r\n";



void setup(){

    pinMode(onModulePin, OUTPUT);
    Serial.begin(115200);    
    
    printf("Starting...\n");
    power_on();
    
    delay(3000);
    
	snprintf(aux_str, sizeof(aux_str), "AT+CPIN=%s", pin);
    sendATcommand2(aux_str, "OK", "ERROR", 2000);
    
    delay(3000);
    
    printf("Connecting to the network...\n");

    while( sendATcommand2("AT+CREG?", "+CREG: 0,1", "+CREG: 0,5", 1000)== 0 );

}


void loop(){
    
 
    // Selects Single-connection mode
    if (sendATcommand2("AT+CIPMUX=0", "OK", "ERROR", 1000) == 1)
    {
        // Waits for status IP INITIAL
        while(sendATcommand("AT+CIPSTATUS", "INITIAL", 500)  == 0 );
        delay(5000);
        
        snprintf(aux_str, sizeof(aux_str), "AT+CSTT=\"%s\",\"%s\",\"%s\"", apn, user_name, password);
        // Sets the APN, user name and password
        if (sendATcommand2(aux_str, "OK",  "ERROR", 30000) == 1)
        {            
            // Waits for status IP START
            while(sendATcommand("AT+CIPSTATUS", "START", 500)  == 0 );
            delay(5000);
            
            // Brings Up Wireless Connection
            if (sendATcommand2("AT+CIICR", "OK", "ERROR", 30000) == 1)
            {
                // Waits for status IP GPRSACT
                while(sendATcommand("AT+CIPSTATUS", "GPRSACT", 500)  == 0 );
                delay(5000);
                
                // Gets Local IP Address
                if (sendATcommand2("AT+CIFSR", ".", "ERROR", 10000) == 1)
                {
                    // Waits for status IP STATUS
                    while(sendATcommand2("AT+CIPSTATUS", "IP STATUS", "", 500)  == 0 );
                    delay(5000);
                    printf("Opening TCP\n");
                    
                    snprintf(aux_str, sizeof(aux_str), "AT+CIPSTART=\"TCP\",\"%s\",\"%s\"", IP_address, port);
                    
                    // Opens a TCP socket
                    if (sendATcommand2(aux_str, "CONNECT OK", "CONNECT FAIL", 30000) == 1)
                    {
                        printf("Connected\n");
                        
                        // Sends some data to the TCP socket
                        sprintf(aux_str,"AT+CIPSEND=%d", strlen(ip_data));
                        if (sendATcommand2(aux_str, ">", "ERROR", 10000) == 1)    
                        {
                            sendATcommand2(ip_data, "SEND OK", "ERROR", 10000);
                        }
                        
                        // Closes the socket
                        sendATcommand2("AT+CIPCLOSE", "CLOSE OK", "ERROR", 10000);
                    }
                    else
                    {
                        printf("Error opening the connection\n");
                    }  
                }
                else
                {
                    printf("Error getting the IP address\n");
                }  
            }
            else
            {
                printf("Error bring up wireless connection\n");
            }
        }
        else
        {
            printf("Error setting the APN\n");
        } 
    }
    else
    {
        printf("Error setting the single connection\n");
    }
    
    sendATcommand2("AT+CIPSHUT", "OK", "ERROR", 10000);
    delay(10000);
}

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);    
        }
    }
    
}

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

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

    memset(response, '\0', 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();
            printf("%c",response[x]);
            x++;
            // check if the desired answer  is in the response of the module
            if (strstr(response, expected_answer) != NULL)    
            {
				printf("\n");
                answer = 1;
            }
        }
    }
    // Waits for the asnwer with time out
    while((answer == 0) && ((millis() - previous) < timeout));    

        return answer;
}

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

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

    memset(response, '\0', 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();
            printf("%c",response[x]);
            x++;
            // check if the desired answer 1  is in the response of the module
            if (strstr(response, expected_answer1) != NULL)    
            {
				printf("\n");
                answer = 1;
            }
            // check if the desired answer 2 is in the response of the module
            else if (strstr(response, expected_answer2) != NULL)    
            {
				printf("\n");
                answer = 2;
            }
        }
    }
    // Waits for the asnwer with time out
    while((answer == 0) && ((millis() - previous) < timeout));    

    return answer;
}

int main (){
    setup();
    while(1){
        loop();
    }
    return (0);
}

    

Multiple client

SIM908 allows to use 8 connections simultaneously. Here is the example code with a UDP and TCP connections.

Arduino code:

Code:
/*  
 *  GPRS+GPS Quadband Module (SIM908)
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  a
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           2.0
 *  Design:            David GascĂłn 
 *  Implementation:    Alejandro Gallego & Marcos Martinez
 */
 
 
int8_t answer;
int onModulePin= 2;
char aux_str[100];

char pin[]="*******";
char apn[]="*******";
char user_name[]="*******";
char password[]="*******";
char IP_address[]="*******";
char port[]="*******";

char ip_data[40]="Test string from GPRS shield\r\n";



void setup(){

    pinMode(onModulePin, OUTPUT);
    Serial.begin(115200);    
    
    Serial.println("Starting...");
    power_on();
    
    delay(3000);
    
    //sets the PIN code
    snprintf(aux_str, sizeof(aux_str), "AT+CPIN=%s", pin);
    sendATcommand(aux_str, "OK", 2000);
    
    delay(3000);
    
    Serial.println("Connecting to the network...");

    while( sendATcommand2("AT+CREG?", "+CREG: 0,1", "+CREG: 0,5", 1000) == 0 );

}


void loop(){
    
    
    // Selects Multi-connection mode
    if (sendATcommand2("AT+CIPMUX=1", "OK", "ERROR", 1000) == 1)
    {
        // Waits for status IP INITIAL
        while(sendATcommand2("AT+CIPSTATUS", "INITIAL", "", 500)  == 0 );
        delay(5000);
        
        snprintf(aux_str, sizeof(aux_str), "AT+CSTT=\"%s\",\"%s\",\"%s\"", apn, user_name, password);
        
        // Sets the APN, user name and password
        if (sendATcommand2(aux_str, "OK",  "ERROR", 30000) == 1)
        {
            // Waits for status IP START
            while(sendATcommand("AT+CIPSTATUS", "START", 500)  == 0 );
            delay(5000);
            
            // Brings Up Wireless Connection
            if (sendATcommand2("AT+CIICR", "OK", "ERROR", 30000) == 1)
            {
                // Waits for status IP GPRSACT
                while(sendATcommand("AT+CIPSTATUS", "GPRSACT", 500)  == 0 );
                delay(5000);
                
                // Gets Local IP Address
                if (sendATcommand2("AT+CIFSR", ".", "ERROR", 10000) == 1)
                {
                    // Waits for status IP STATUS
                    while(sendATcommand("AT+CIPSTATUS", "IP STATUS", 500)  == 0 );
                    delay(5000);
                    Serial.println("Opening TCP");
                    
                    snprintf(aux_str, sizeof(aux_str), "AT+CIPSTART=1,\"TCP\",\"%s\",\"%s\"", IP_address, port);
                    
                    // Opens a TCP socket with connection 1
                    if (sendATcommand2(aux_str, "CONNECT OK", "CONNECT FAIL", 30000) == 1)
                    {
                        Serial.println("Connected");
                        
                        // Sends some data to the TCP socket
                        sprintf(aux_str,"AT+CIPSEND=1,%d", strlen(ip_data));
                        if (sendATcommand2(aux_str, ">", "ERROR", 10000) == 1)    
                        {
                            delay(500);
                            sendATcommand2(ip_data, "SEND OK", "ERROR", 10000);
                        }
                        
                        // Closes the socket
                        sendATcommand2("AT+CIPCLOSE=1", "CLOSE OK", "ERROR", 10000);
                    }
                    else
                    {
                        Serial.println("Error opening the connection 1");
                    }  
                    
                }
                else
                {
                    Serial.println("Error getting the IP address");
                }  
            }
            else
            {
                Serial.println("Error bring up wireless connection");
            }
        }
        else
        {
            Serial.println("Error setting the APN");
        } 
    }
    else
    {
        Serial.println("Error setting the multi-connection");
    }
    
    sendATcommand2("AT+CIPSHUT", "OK", "ERROR", 10000);
    delay(10000);
}

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);    
        }
    }
    
}

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, '\0', 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, '\0', 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
            else if (strstr(response, expected_answer2) != NULL)    
            {
                answer = 2;
            }
        }
    }
    // Waits for the asnwer with time out
    while((answer == 0) && ((millis() - previous) < timeout));    

    return answer;
}
    

Raspberry Pi code:

Code:
/*  
 *  GPRS+GPS Quadband Module (SIM908)
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  a
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           2.0
 *  Design:            David GascĂłn 
 *  Implementation:    Alejandro Gallego & Marcos Martinez
 */
 
 //Include arduPi library
#include "arduPi.h"

 int8_t sendATcommand2(const char* ATcommand, const char* expected_answer1, const char* expected_answer2, unsigned int timeout);
 int8_t sendATcommand(const char* ATcommand, const char* expected_answer, unsigned int timeout);
 void power_on();
 
int8_t answer;
int onModulePin= 2;
char aux_str[100];

char pin[]="*******";
char apn[]="*******";
char user_name[]="*******";
char password[]="*******";
char IP_address[]="*******";
char port[]="*******";

char ip_data[40]="Test string from GPRS shield\r\n";



void setup(){

    pinMode(onModulePin, OUTPUT);
    Serial.begin(115200);    
    
    printf("Starting...\n");
    power_on();
    
    delay(3000);
    
    // sets the PIN code
    snprintf(aux_str, sizeof(aux_str), "AT+CPIN=%s", pin);
    sendATcommand2(aux_str, "OK", "ERROR", 2000);
    
    delay(3000);
    
    printf("Connecting to the network...\n");

    while( sendATcommand2("AT+CREG?", "+CREG: 0,1", "+CREG: 0,5", 1000) == 0 );

}


void loop(){
    
    
    // Selects Multi-connection mode
    if (sendATcommand2("AT+CIPMUX=1", "OK", "ERROR", 1000) == 1)
    {
        // Waits for status IP INITIAL
        while(sendATcommand("AT+CIPSTATUS", "INITIAL", 500)  == 0 );
        delay(5000);
        
        snprintf(aux_str, sizeof(aux_str), "AT+CSTT=\"%s\",\"%s\",\"%s\"", apn, user_name, password);
        // Sets the APN, user name and password
        if (sendATcommand2(aux_str, "OK",  "ERROR", 30000) == 1)
        {
            // Waits for status IP START
            while(sendATcommand("AT+CIPSTATUS", "START", 500)  == 0 );
            delay(5000);
            
            // Brings Up Wireless Connection
            if (sendATcommand2("AT+CIICR", "OK", "ERROR", 30000) == 1)
            {
                // Waits for status IP GPRSACT
                while(sendATcommand("AT+CIPSTATUS", "GPRSACT", 500)  == 0 );
                delay(5000);
                
                // Gets Local IP Address
                if (sendATcommand2("AT+CIFSR", ".", "ERROR", 10000) == 1)
                {
                    // Waits for status IP STATUS
                    while(sendATcommand2("AT+CIPSTATUS", "IP STATUS", "", 500)  == 0 );
                    delay(5000);
                    printf("Opening TCP\n");
                    
                    snprintf(aux_str, sizeof(aux_str), "AT+CIPSTART=1,\"TCP\",\"%s\",\"%s\"", IP_address, port);
                    
                    // Opens a TCP socket with connection 1
                    if (sendATcommand2(aux_str, "CONNECT OK", "CONNECT FAIL", 30000) == 1)
                    {
                        printf("Connected\n");
                        
                        // Sends some data to the TCP socket
                        sprintf(aux_str,"AT+CIPSEND=1,%d", strlen(ip_data));
                        if (sendATcommand2(aux_str, ">", "ERROR", 10000) == 1)    
                        {
                            //delay(500);
                            sendATcommand2(ip_data, "SEND OK", "ERROR", 10000);
                        }
                        
                        // Closes the socket
                        sendATcommand2("AT+CIPCLOSE=1", "CLOSE OK", "ERROR", 10000);
                    }
                    else
                    {
                        printf("Error opening the connection 1\n");
                    }  
                    
                }
                else
                {
                    printf("Error getting the IP address\n");
                }  
            }
            else
            {
                printf("Error bring up wireless connection\n");
            }
        }
        else
        {
            printf("Error setting the APN\n");
        } 
    }
    else
    {
        printf("Error setting the multi-connection\n");
    }
    
    sendATcommand2("AT+CIPSHUT", "OK", "ERROR", 10000);
    delay(10000);
}

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);    
        }
    }
    
}

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

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

    memset(response, '\0', 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();
            printf("%c",response[x]);
            x++;
            // check if the desired answer  is in the response of the module
            if (strstr(response, expected_answer) != NULL)    
            {
				printf("\n");
                answer = 1;
            }
        }
    }
    // Waits for the asnwer with time out
    while((answer == 0) && ((millis() - previous) < timeout));    

        return answer;
}

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

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

    memset(response, '\0', 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();
            printf("%c",response[x]);
            x++;
            // check if the desired answer 1  is in the response of the module
            if (strstr(response, expected_answer1) != NULL)    
            {
				printf("\n");
                answer = 1;
            }
            // check if the desired answer 2 is in the response of the module
            else if (strstr(response, expected_answer2) != NULL)    
            {
				printf("\n");
                answer = 2;
            }
        }
    }
    // Waits for the asnwer with time out
    while((answer == 0) && ((millis() - previous) < timeout));    

    return answer;
}

int main (){
    setup();
    while(1){
        loop();
    }
    return (0);
}

    

Command summary

AT command Response Description
AT+CIPMUX= OK Selects single connection (0) or multiple connection (1)
AT+CSTT="myAPN" OK Sets APN
AT+CIICR   Brings up wireless connection
AT+CIFSR   Get local IP address
AT+CIPSTART   Establishes a connection with a server.
AT+CIPSEND   Sends data when the a connection is established.
AT+CIPCLOSE   Closes the connection

Step 8: Using the shield in standalone mode - HTTP

SIM908 can launch a HTTP operation like GET or POST. Here is an example with GET operation:

Arduino code:

Code:
/*  
 *  GPRS+GPS Quadband Module (SIM908)
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  a
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           2.0
 *  Design:            David GascĂłn 
 *  Implementation:    Alejandro Gallego & Marcos Martinez
 */


int8_t answer;
int onModulePin= 2;

char data[512];
int data_size;

char aux_str[100];
char aux;
int x = 0;

char pin[]="*******";
char apn[]="*******";
char user_name[]="*******";
char password[]="*******";

char url[ ]="test.libelium.com/test-get-post.php?a=1&b=2";


void setup(){

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

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

    delay(3000);
   
    //sets the PIN code
    snprintf(aux_str, sizeof(aux_str), "AT+CPIN=%s", pin);
    sendATcommand(aux_str, "OK", 2000);

    delay(3000);

    while (sendATcommand2("AT+CREG?", "+CREG: 0,1", "+CREG: 0,5", 2000) == 0);

    // sets APN , user name and password
    sendATcommand("AT+SAPBR=3,1,\"Contype\",\"GPRS\"", "OK", 2000);
    snprintf(aux_str, sizeof(aux_str), "AT+SAPBR=3,1,\"APN\",\"%s\"", apn);
    sendATcommand(aux_str, "OK", 2000);
    
    snprintf(aux_str, sizeof(aux_str), "AT+SAPBR=3,1,\"USER\",\"%s\"", user_name);
    sendATcommand(aux_str, "OK", 2000);
    
    snprintf(aux_str, sizeof(aux_str), "AT+SAPBR=3,1,\"PWD\",\"%s\"", password);
    sendATcommand(aux_str, "OK", 2000);

    while (sendATcommand("AT+SAPBR=1,1", "OK", 20000) == 0)
    {
        delay(5000);
    }


}
void loop(){
    // Initializes HTTP service
    answer = sendATcommand("AT+HTTPINIT", "OK", 10000);
    if (answer == 1)
    {
        // Sets CID parameter
        answer = sendATcommand("AT+HTTPPARA=\"CID\",1", "OK", 5000);
        if (answer == 1)
        {
            // Sets url 
            
            snprintf(aux_str, sizeof(aux_str), "AT+HTTPPARA=\"URL\",\"%s\"", url);
            
            answer = sendATcommand(aux_str, "OK", 5000);
            if (answer == 1)
            {
                // Starts GET action
                answer = sendATcommand("AT+HTTPACTION=0", "+HTTPACTION:0,200", 10000);
                
                if (answer == 1)
                {
                    x=0;
                    do{
                        sprintf(aux_str, "AT+HTTPREAD=%d,100", x);
                        if (sendATcommand2(aux_str, "+HTTPREAD:", "ERROR", 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++)
                                {
                                    data[x] = Serial.read();
                                    x++;
                                }
                                data[x] = '\0';
                            }
                            else
                            {
                                Serial.println("Download finished");    
                            }
                        }
                        else if (answer == 2)
                        {
                            Serial.println("Error from HTTP");
                        }
                        else
                        {
                            Serial.println("No more data available");
                            data_size = 0;
                        }
                        
                        sendATcommand("", "+HTTPACTION:0,200", 20000);
                    }while (data_size > 0);
                    
                    Serial.print("Data received: ");
                    Serial.println(data);
                }
                else
                {
                    Serial.println("Error getting the url");
                }
            }
            else
            {
                Serial.println("Error setting the url");
            }
        }
        else
        {
            Serial.println("Error setting the CID");
        }    
    }
    else
    {
        Serial.println("Error initializating");
    }
    
    sendATcommand("AT+HTTPTERM", "OK", 5000);

    delay(5000);

}

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);    
        }
    }

}


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

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

    memset(response, '\0', 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){    
            response[x] = Serial.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;
}



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, '\0', 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){    
            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;
}
    

Raspberry Pi code:

Code:
/*  
 *  GPRS+GPS Quadband Module (SIM908)
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  a
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           2.0
 *  Design:            David GascĂłn 
 *  Implementation:    Alejandro Gallego & Marcos Martinez
 */

//Include arduPi library
#include "arduPi.h"

int8_t sendATcommand2(const char* ATcommand, const char* expected_answer1, const char* expected_answer2, unsigned int timeout);
int8_t sendATcommand(const char* ATcommand, const char* expected_answer, unsigned int timeout);

void power_on();


int8_t answer;
int onModulePin= 2;

char data[512];
int data_size;

char aux_str[100];
char aux;
int x = 0;

char pin[]="*******";
char apn[]="*******";
char user_name[]="*******";
char password[]="*******";

char url[ ]="test.libelium.com/test-get-post.php?a=1&b=2";

void setup(){

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

    printf("Starting...\n");
    power_on();

    delay(3000);

    //sets the PIN code
    snprintf(aux_str, sizeof(aux_str), "AT+CPIN=%s", pin);
    sendATcommand(aux_str, "OK", 2000);

    delay(3000);

    while (sendATcommand2("AT+CREG?", "+CREG: 0,1", "+CREG: 0,5", 2000) == 0);


    // sets APN , user name and password
    sendATcommand("AT+SAPBR=3,1,\"Contype\",\"GPRS\"", "OK", 2000);
    snprintf(aux_str, sizeof(aux_str), "AT+SAPBR=3,1,\"APN\",\"%s\"", apn);
    sendATcommand(aux_str, "OK", 2000);
    
    snprintf(aux_str, sizeof(aux_str), "AT+SAPBR=3,1,\"USER\",\"%s\"", user_name);
    sendATcommand(aux_str, "OK", 2000);
    
    snprintf(aux_str, sizeof(aux_str), "AT+SAPBR=3,1,\"PWD\",\"%s\"", password);
    sendATcommand(aux_str, "OK", 2000);

    while (sendATcommand("AT+SAPBR=1,1", "OK", 20000) == 0)
    {
        delay(5000);
    }


}
void loop(){
    // Initializes HTTP service
    answer = sendATcommand("AT+HTTPINIT", "OK", 10000);
    if (answer == 1)
    {
        // Sets CID parameter
        answer = sendATcommand("AT+HTTPPARA=\"CID\",1", "OK", 5000);
        if (answer == 1)
        {
            // Sets url 
            
            snprintf(aux_str, sizeof(aux_str), "AT+HTTPPARA=\"URL\",\"%s\"", url);
            answer = sendATcommand(aux_str, "OK", 5000);
            if (answer == 1)
            {
                // Starts GET action
                answer = sendATcommand("AT+HTTPACTION=0", "+HTTPACTION:0,200", 10000);
                
                if (answer == 1)
                {
                    x=0;
                    do{
                        sprintf(aux_str, "AT+HTTPREAD=%d,100", x);
                        if (sendATcommand2(aux_str, "+HTTPREAD:", "ERROR", 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);

                            printf("Data received: %d\n",data_size);

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

                                for (int y = 0; y < data_size; y++)
                                {
                                    data[x] = Serial.read();
                                    x++;
                                }
                                data[x] = '\0';
                            }
                            else
                            {
                                printf("Download finished\n");    
                            }
                        }
                        else if (answer == 2)
                        {
                            printf("Error from HTTP\n");
                        }
                        else
                        {
                            printf("No more data available\n");
                            data_size = 0;
                        }
                        
                        sendATcommand("", "+HTTPACTION:0,200", 20000);
                    }while (data_size > 0);
                    
                    printf("Data received: %s\n",data);
                    
                }
                else
                {
                    printf("Error getting the url\n");
                }
            }
            else
            {
                printf("Error setting the url\n");
            }
        }
        else
        {
            printf("Error setting the CID\n");
        }    
    }
    else
    {
        printf("Error initializating\n");
    }
    
    sendATcommand("AT+HTTPTERM", "OK", 5000);

    delay(5000);

}

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);    
        }
    }

}


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

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

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

    delay(100);

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


        x = 0;
    previous = millis();

    // this loop waits for the answer
    do{
        if(Serial.available() != 0){    
            response[x] = Serial.read();
            printf("%c",response[x]);
            x++;
            // check if the desired answer is in the response of the module
            if (strstr(response, expected_answer1) != NULL)    
            {
				printf("\n");
                answer = 1;
            }
        }
        // Waits for the asnwer with time out
    }
    while((answer == 0) && ((millis() - previous) < timeout));    

    return answer;
}



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

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

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

    delay(100);

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


        x = 0;
    previous = millis();

    // this loop waits for the answer
    do{        
        if(Serial.available() != 0){    
            response[x] = Serial.read();
            printf("%c",response[x]);
            x++;
            // check if the desired answer 1 is in the response of the module
            if (strstr(response, expected_answer1) != NULL)    
            {
				printf("\n");
                answer = 1;
            }
            // check if the desired answer 2 is in the response of the module
            if (strstr(response, expected_answer2) != NULL)    
            {
				printf("\n");
                answer = 2;
            }
        }
        // Waits for the asnwer with time out
    }while((answer == 0) && ((millis() - previous) < timeout));    

    return answer;
}

int main (){
    setup();
    while(1){
        loop();
    }
    return (0);
}

    

Command summary

AT command Response Description
AT+SAPBR OK Configures GPRS profile
AT+HTTPINIT OK Initializes HTTP service
AT+HTTPPARA OK Configures HTTP parameters
AT+HTTPACTION=0 OK Sets HTTP Method Action , GET in this chase.
AT+HTTPREAD   Reads HTTP data
AT+HTTPTERM OK Closes the opened HTTP session.

Step 9: Using the shield in standalone mode - GPS

The SIM908 includes a GPS receive. The next sketch shows how to power on the GPS and get the NMEA strings when the satellites had been fixed.

Arduino code:

Code:
/*  
 *  GPRS+GPS Quadband Module (SIM908)
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  a
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           2.0
 *  Design:            David GascĂłn 
 *  Implementation:    Alejandro Gallego & Marcos Martinez
 */
 
 
int8_t answer;
int onModulePin= 2;
int counter;
long previous;


char Basic_str[100];
char GGA_str[100];
char GLL_str[100];
char RMC_str[100];
char VTG_str[100];
char ZDA_str[100];

void setup(){
    
    pinMode(onModulePin, OUTPUT);
    Serial.begin(115200);   
    
    Serial.println("Starting...");
    power_on();
    
    delay(3000);
    
    sendATcommand("AT+CGPSPWR=1", "OK", 2000);
    sendATcommand("AT+CGPSRST=0", "OK", 2000);
    
    
    // waits for fix GPS
    while( (sendATcommand("AT+CGPSSTATUS?", "2D Fix", 5000) || 
            sendATcommand("AT+CGPSSTATUS?", "3D Fix", 5000)) == 0 );
    

}

void loop(){
    // Basic
    // Clean the input buffer
    while( Serial.available() > 0) Serial.read();    
    delay(100);
    // request Basic string
    sendATcommand("AT+CGPSINF=0", "AT+CGPSINF=0\r\n\r\n", 2000);
    
    counter = 0;
    answer = 0;
    memset(Basic_str, '\0', 100);    // Initialize the string
    previous = millis();
    // this loop waits for the NMEA string
    do{

        if(Serial.available() != 0){    
            Basic_str[counter] = Serial.read();
            counter++;
            // check if the desired answer is in the response of the module
            if (strstr(Basic_str, "OK") != NULL)    
            {
                answer = 1;
            }
        }
        // Waits for the asnwer with time out
    }while((answer == 0) && ((millis() - previous) < 2000));  
    
    Basic_str[counter-3] = '\0';
    
    //**********************************************************
    // GGA
    // Clean the input buffer
    while( Serial.available() > 0) Serial.read();    
    delay(100);
    // request GGA string
    sendATcommand("AT+CGPSINF=2", "AT+CGPSINF=2\r\n\r\n", 2000);
    
    counter = 0;
    answer = 0;
    memset(GGA_str, '\0', 100);    // Initialize the string
    previous = millis();
    // this loop waits for the NMEA string
    do{

        if(Serial.available() != 0){    
            GGA_str[counter] = Serial.read();
            counter++;
            // check if the desired answer is in the response of the module
            if (strstr(GGA_str, "OK") != NULL)    
            {
                answer = 1;
            }
        }
        // Waits for the asnwer with time out
    }while((answer == 0) && ((millis() - previous) < 2000));  
    
    GGA_str[counter-3] = '\0';
    
    //**********************************************************
    // GLL
    // Clean the input buffer
    while( Serial.available() > 0) Serial.read();    
       
    delay(100);
    // request GLL string
    sendATcommand("AT+CGPSINF=4", "AT+CGPSINF=4\r\n\r\n", 2000);   
    
    counter = 0;
    answer = 0;
    memset(GLL_str, '\0', 100);    // Initialize the string
    previous = millis();
    // this loop waits for the NMEA string
    do{

        if(Serial.available() != 0){    
            GLL_str[counter] = Serial.read();
            counter++;
            // check if the desired answer is in the response of the module
            if (strstr(GLL_str, "OK") != NULL)    
            {
                answer = 1;
            }
        }
        // Waits for the asnwer with time out
    }while((answer == 0) && ((millis() - previous) < 2000)); 
    
    GLL_str[counter-3] = '\0';
        
    //**********************************************************
    // RMC
    // Clean the input buffer
    while( Serial.available() > 0) Serial.read();    
       
    delay(100);
    // request RMC string 
    sendATcommand("AT+CGPSINF=32", "AT+CGPSINF=32\r\n\r\n", 2000);
    
    counter = 0;
    answer = 0;
    memset(RMC_str, '\0', 100);    // Initialize the string
    previous = millis();
    // this loop waits for the NMEA string
    do{

        if(Serial.available() != 0){    
            RMC_str[counter] = Serial.read();
            counter++;
            // check if the desired answer is in the response of the module
            if (strstr(RMC_str, "OK") != NULL)    
            {
                answer = 1;
            }
        }
        // Waits for the asnwer with time out
    }while((answer == 0) && ((millis() - previous) < 2000)); 
    
    RMC_str[counter-3] = '\0';
    
    //**********************************************************
    // VTG
    // Clean the input buffer
    while( Serial.available() > 0) Serial.read();    
       
    delay(100);
    // request VTG string
    sendATcommand("AT+CGPSINF=64", "AT+CGPSINF=64\r\n\r\n", 2000); 
    
    counter = 0;
    answer = 0;
    memset(VTG_str, '\0', 100);    // Initialize the string
    previous = millis();
    // this loop waits for the NMEA string
    do{

        if(Serial.available() != 0){    
            VTG_str[counter] = Serial.read();
            counter++;
            // check if the desired answer is in the response of the module
            if (strstr(VTG_str, "OK") != NULL)    
            {
                answer = 1;
            }
        }
        // Waits for the asnwer with time out
    }while((answer == 0) && ((millis() - previous) < 2000)); 
    
    VTG_str[counter-3] = '\0';
    
    //**********************************************************
    // ZDA
    // Clean the input buffer
    while( Serial.available() > 0) Serial.read();    
       
    delay(100);
    // request ZDA string
    sendATcommand("AT+CGPSINF=128", "AT+CGPSINF=128\r\n\r\n", 2000);
    
    counter = 0;
    answer = 0;
    memset(ZDA_str, '\0', 100);    // Initialize the string
    previous = millis();
    // this loop waits for the NMEA string
    do{

        if(Serial.available() != 0){    
            ZDA_str[counter] = Serial.read();
            counter++;
            // check if the desired answer is in the response of the module
            if (strstr(ZDA_str, "OK") != NULL)    
            {
                answer = 1;
            }
        }
        // Waits for the asnwer with time out
    }while((answer == 0) && ((millis() - previous) < 2000));
    
    ZDA_str[counter-3] = '\0';
    
    Serial.println("*************************************************");
    Serial.print("Basic string: ");
    Serial.println(Basic_str);
    Serial.print("GGA string: ");
    Serial.println(GGA_str);
    Serial.print("GLL string: ");
    Serial.println(GLL_str);
    Serial.print("RMC string: ");
    Serial.println(RMC_str);
    Serial.print("VTG string: ");
    Serial.println(VTG_str);
    Serial.print("ZDA string: ");
    Serial.println(ZDA_str);
   
    delay(15000);

}

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);    
        }
    }
    
}


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

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

    memset(response, '\0', 100);    // Initialize the string
    
    delay(100);
    
    // Clean the input buffer
    while( Serial.available() > 0) Serial.read();    
    
    Serial.println(ATcommand);    // Send the AT command 


    x = 0;
    previous = millis();

    // this loop waits for the answer
    do{

        if(Serial.available() != 0){    
            response[x] = Serial.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;
}
    

Raspberry Pi code:

Code:
/*  
 *  GPRS+GPS Quadband Module (SIM908)
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  a
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           2.0
 *  Design:            David GascĂłn 
 *  Implementation:    Alejandro Gallego & Marcos Martinez
 */
 
 //Include arduPi library
 #include "arduPi.h"

 int8_t sendATcommand(const char* ATcommand, const char* expected_answer1, unsigned int timeout);
 void power_on();
 
int8_t answer;
int onModulePin= 2;
int counter;
long previous;


char Basic_str[100];
char GGA_str[100];
char GLL_str[100];
char RMC_str[100];
char VTG_str[100];
char ZDA_str[100];

void setup(){
    
    pinMode(onModulePin, OUTPUT);
    Serial.begin(115200);   
    
    printf("Starting...\n");
    power_on();
    
    delay(3000);
    
      
    sendATcommand("AT+CGPSPWR=1", "OK", 2000);
    sendATcommand("AT+CGPSRST=0", "OK", 2000);
    
    
    // waits for fix GPS
    while( (sendATcommand("AT+CGPSSTATUS?", "2D Fix", 5000) || 
            sendATcommand("AT+CGPSSTATUS?", "3D Fix", 5000)) == 0 );
    

}

void loop(){
    // Basic
    // Clean the input buffer
    while( Serial.available() > 0) Serial.read();    
    delay(100);
    // request Basic string
    sendATcommand("AT+CGPSINF=0", "AT+CGPSINF=0\r\n\r\n", 2000);
    
    counter = 0;
    answer = 0;
    memset(Basic_str, '\0', 100);    // Initialize the string
    previous = millis();
    // this loop waits for the NMEA string
    do{

        if(Serial.available() != 0){    
            Basic_str[counter] = Serial.read();
            counter++;
            // check if the desired answer is in the response of the module
            if (strstr(Basic_str, "OK") != NULL)    
            {
                answer = 1;
            }
        }
        // Waits for the asnwer with time out
    }while((answer == 0) && ((millis() - previous) < 2000));  
    
    Basic_str[counter-3] = '\0';
    
    //**********************************************************
    // GGA
    // Clean the input buffer
    while( Serial.available() > 0) Serial.read();    
    delay(100);
    // request GGA string
    sendATcommand("AT+CGPSINF=2", "AT+CGPSINF=2\r\n\r\n", 2000);
    
    counter = 0;
    answer = 0;
    memset(GGA_str, '\0', 100);    // Initialize the string
    previous = millis();
    // this loop waits for the NMEA string
    do{

        if(Serial.available() != 0){    
            GGA_str[counter] = Serial.read();
            counter++;
            // check if the desired answer is in the response of the module
            if (strstr(GGA_str, "OK") != NULL)    
            {
                answer = 1;
            }
        }
        // Waits for the asnwer with time out
    }while((answer == 0) && ((millis() - previous) < 2000));  
    
    GGA_str[counter-3] = '\0';
    
    //**********************************************************
    // GLL
    // Clean the input buffer
    while( Serial.available() > 0) Serial.read();    
       
    delay(100);
    // request GLL string
    sendATcommand("AT+CGPSINF=4", "AT+CGPSINF=4\r\n\r\n", 2000);   
    
    counter = 0;
    answer = 0;
    memset(GLL_str, '\0', 100);    // Initialize the string
    previous = millis();
    // this loop waits for the NMEA string
    do{

        if(Serial.available() != 0){    
            GLL_str[counter] = Serial.read();
            counter++;
            // check if the desired answer is in the response of the module
            if (strstr(GLL_str, "OK") != NULL)    
            {
                answer = 1;
            }
        }
        // Waits for the asnwer with time out
    }while((answer == 0) && ((millis() - previous) < 2000)); 
    
    GLL_str[counter-3] = '\0';
        
    //**********************************************************
    // RMC
    // Clean the input buffer
    while( Serial.available() > 0) Serial.read();    
       
    delay(100);
    // request RMC string 
    sendATcommand("AT+CGPSINF=32", "AT+CGPSINF=32\r\n\r\n", 2000);
    
    counter = 0;
    answer = 0;
    memset(RMC_str, '\0', 100);    // Initialize the string
    previous = millis();
    // this loop waits for the NMEA string
    do{

        if(Serial.available() != 0){    
            RMC_str[counter] = Serial.read();
            counter++;
            // check if the desired answer is in the response of the module
            if (strstr(RMC_str, "OK") != NULL)    
            {
                answer = 1;
            }
        }
        // Waits for the asnwer with time out
    }while((answer == 0) && ((millis() - previous) < 2000)); 
    
    RMC_str[counter-3] = '\0';
    
    //**********************************************************
    // VTG
    // Clean the input buffer
    while( Serial.available() > 0) Serial.read();    
       
    delay(100);
    // request VTG string
    sendATcommand("AT+CGPSINF=64", "AT+CGPSINF=64\r\n\r\n", 2000); 
    
    counter = 0;
    answer = 0;
    memset(VTG_str, '\0', 100);    // Initialize the string
    previous = millis();
    // this loop waits for the NMEA string
    do{

        if(Serial.available() != 0){    
            VTG_str[counter] = Serial.read();
            counter++;
            // check if the desired answer is in the response of the module
            if (strstr(VTG_str, "OK") != NULL)    
            {
                answer = 1;
            }
        }
        // Waits for the asnwer with time out
    }while((answer == 0) && ((millis() - previous) < 2000)); 
    
    VTG_str[counter-3] = '\0';
    
    //**********************************************************
    // ZDA
    // Clean the input buffer
    while( Serial.available() > 0) Serial.read();    
       
    delay(100);
    // request ZDA string
    sendATcommand("AT+CGPSINF=128", "AT+CGPSINF=128\r\n\r\n", 2000);
    
    counter = 0;
    answer = 0;
    memset(ZDA_str, '\0', 100);    // Initialize the string
    previous = millis();
    // this loop waits for the NMEA string
    do{

        if(Serial.available() != 0){    
            ZDA_str[counter] = Serial.read();
            counter++;
            // check if the desired answer is in the response of the module
            if (strstr(ZDA_str, "OK") != NULL)    
            {
                answer = 1;
            }
        }
        // Waits for the asnwer with time out
    }while((answer == 0) && ((millis() - previous) < 2000));
    
    ZDA_str[counter-3] = '\0';
    
    printf("*************************************************\n");
    printf("Basic string: ");
    printf("%s\n",Basic_str);
    printf("GGA string: ");
    printf("%s\n",GGA_str);
    printf("GLL string: ");
    printf("%s\n",GLL_str);
    printf("RMC string: ");
    printf("%s\n",RMC_str);
    printf("VTG string: ");
    printf("%s\n",VTG_str);
    printf("ZDA string: ");
    printf("%s\n",ZDA_str);
   
    delay(15000);

}

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);    
        }
    }
    
}


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

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

    memset(response, '\0', 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();
            printf("%c",response[x]);
            x++;
            // check if the desired answer  is in the response of the module
            if (strstr(response, expected_answer) != NULL)    
            {
				printf("\n");
                answer = 1;
            }
        }
    }
    // Waits for the asnwer with time out
    while((answer == 0) && ((millis() - previous) < timeout));    

        return answer;
}

int main(){
    setup();
    while(1){loop();}
    return 0;
}

    

Command summary

AT command Response Description
AT+CGPSPWR OK Powers the GPS
AT+CGPSRST OK Sets the reset mode
AT+CGPSSTATUS Gets the status: Unknown, Not Fix, 2D Fix and 3D Fix
AT+CGPSINF NMEA string Gets NMEA strings

Realtime geolocation tracking

In this step we use an Arduino UNO with the GPRS+GPS shield to send GPS coordinates to a computer that it shows the position of the Arduino in Google Maps.

First step. Load the next sketch into your arduino and then assemble the GPRS+GPS shield with the antennas and the simcard installed. Remember, you must configure your APN, login and password. If you don't do this, the GPRS+GPS cannot connect to the GPRS network. Also, you must set the URL with the IP address of your computer (external IP, not the LAN IP address) or your server's domain.

Code:
/*  
 *  GPRS+GPS Quadband Module (SIM908)
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  a
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           2.0
 *  Design:            David GascĂłn 
 *  Implementation:    Alejandro Gallego & Marcos Martinez
 */


int8_t answer;
int onModulePin= 2;

char data[100];
int data_size;

char aux_str[100];
char aux;
int x = 0;
char N_S,W_E;

char url[] = "http://pruebas.libelium.com/demo_sim908.php";
char frame[200];

char pin[]="*******";
char apn[]="*******";
char user_name[]="*******";
char password[]="*******";

char latitude[15];
char longitude[15];
char altitude[6];
char date[16];
char time[7];
char satellites[3];
char speedOTG[10];
char course[10];


void setup(){

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

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

    delay(3000);

    //sets the PIN code
    snprintf(aux_str, sizeof(aux_str), "AT+CPIN=%s", pin);
    sendATcommand(aux_str, "OK", 2000);

    delay(3000);
    
    // starts the GPS and waits for signal
    while ( start_GPS() == 0);

    while (sendATcommand("AT+CREG?", "+CREG: 0,1", 2000) == 0);

    // sets APN , user name and password
    sendATcommand("AT+SAPBR=3,1,\"Contype\",\"GPRS\"", "OK", 2000);
    snprintf(aux_str, sizeof(aux_str), "AT+SAPBR=3,1,\"APN\",\"%s\"", apn);
    sendATcommand(aux_str, "OK", 2000);
    
    snprintf(aux_str, sizeof(aux_str), "AT+SAPBR=3,1,\"USER\",\"%s\"", user_name);
    sendATcommand(aux_str, "OK", 2000);
    
    snprintf(aux_str, sizeof(aux_str), "AT+SAPBR=3,1,\"PWD\",\"%s\"", password);
    sendATcommand(aux_str, "OK", 2000);

    // gets the GPRS bearer
    while (sendATcommand("AT+SAPBR=1,1", "OK", 20000) == 0)
    {
        delay(5000);
    }

}

void loop(){

    // gets GPS data
    get_GPS();
    
    // sends GPS data to the script
    send_HTTP();

    delay(5000);

}

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);    
        }
    }

}

int8_t start_GPS(){

    unsigned long previous;

    previous = millis();
    // starts the GPS
    sendATcommand("AT+CGPSPWR=1", "OK", 2000);
    sendATcommand("AT+CGPSRST=0", "OK", 2000);

    // waits for fix GPS
    while(( (sendATcommand("AT+CGPSSTATUS?", "2D Fix", 5000) || 
        sendATcommand("AT+CGPSSTATUS?", "3D Fix", 5000)) == 0 ) && 
        ((millis() - previous) < 90000));

    if ((millis() - previous) < 90000)
    {
        return 1;
    }
    else
    {
        return 0;    
    }
}

int8_t get_GPS(){

    int8_t counter, answer;
    long previous;

    // First get the NMEA string
    // Clean the input buffer
    while( Serial.available() > 0) Serial.read(); 
    // request Basic string
    sendATcommand("AT+CGPSINF=0", "AT+CGPSINF=0\r\n\r\n", 2000);

    counter = 0;
    answer = 0;
    memset(frame, '\0', 100);    // Initialize the string
    previous = millis();
    // this loop waits for the NMEA string
    do{

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

    frame[counter-3] = '\0'; 
    
    // Parses the string 
    strtok(frame, ",");
    strcpy(longitude,strtok(NULL, ",")); // Gets longitude
    strcpy(latitude,strtok(NULL, ",")); // Gets latitude
    strcpy(altitude,strtok(NULL, ".")); // Gets altitude 
    strtok(NULL, ",");    
    strcpy(date,strtok(NULL, ".")); // Gets date
    strtok(NULL, ",");
    strtok(NULL, ",");  
    strcpy(satellites,strtok(NULL, ",")); // Gets satellites
    strcpy(speedOTG,strtok(NULL, ",")); // Gets speed over ground. Unit is knots.
    strcpy(course,strtok(NULL, "\r")); // Gets course

    convert2Degrees(latitude);
    convert2Degrees(longitude);
    
    return answer;
}

/* convert2Degrees ( input ) - performs the conversion from input 
 * parameters in  DD°MM.mmm’ notation to DD.dddddd° notation. 
 * 
 * Sign '+' is set for positive latitudes/longitudes (North, East)
 * Sign '-' is set for negative latitudes/longitudes (South, West)
 *  
 */
int8_t convert2Degrees(char* input){

    float deg;
    float minutes;
    boolean neg = false;    

    //auxiliar variable
    char aux[10];

    if (input[0] == '-')
    {
        neg = true;
        strcpy(aux, strtok(input+1, "."));

    }
    else
    {
        strcpy(aux, strtok(input, "."));
    }

    // convert string to integer and add it to final float variable
    deg = atof(aux);

    strcpy(aux, strtok(NULL, '\0'));
    minutes=atof(aux);
    minutes/=1000000;
    if (deg < 100)
    {
        minutes += deg;
        deg = 0;
    }
    else
    {
        minutes += int(deg) % 100;
        deg = int(deg) / 100;    
    }

    // add minutes to degrees 
    deg=deg+minutes/60;


    if (neg == true)
    {
        deg*=-1.0;
    }

    neg = false;

    if( deg < 0 ){
        neg = true;
        deg*=-1;
    }
    
    float numeroFloat=deg; 
    int parteEntera[10];
    int cifra; 
    long numero=(long)numeroFloat;  
    int size=0;
    
    while(1){
        size=size+1;
        cifra=numero%10;
        numero=numero/10;
        parteEntera[size-1]=cifra; 
        if (numero==0){
            break;
        }
    }
   
    int indice=0;
    if( neg ){
        indice++;
        input[0]='-';
    }
    for (int i=size-1; i >= 0; i--)
    {
        input[indice]=parteEntera[i]+'0'; 
        indice++;
    }

    input[indice]='.';
    indice++;

    numeroFloat=(numeroFloat-(int)numeroFloat);
    for (int i=1; i<=6 ; i++)
    {
        numeroFloat=numeroFloat*10;
        cifra= (long)numeroFloat;          
        numeroFloat=numeroFloat-cifra;
        input[indice]=char(cifra)+48;
        indice++;
    }
    input[indice]='\0';


}

void send_HTTP(){
    
    // Initializes HTTP service
    answer = sendATcommand("AT+HTTPINIT", "OK", 10000);
    if (answer == 1)
    {
        // Sets CID parameter
        answer = sendATcommand("AT+HTTPPARA=\"CID\",1", "OK", 5000);
        if (answer == 1)
        {
            // Sets url 
            sprintf(aux_str, "AT+HTTPPARA=\"URL\",\"%s", url);
            Serial.print(aux_str);
            sprintf(frame, "?visor=false&latitude=%s&longitude=%s&altitude=%s&time=%s&satellites=%s&speedOTG=%s&course=%s",
            latitude, longitude, altitude, date, satellites, speedOTG, course);
            Serial.print(frame);
            answer = sendATcommand("\"", "OK", 5000);
            if (answer == 1)
            {
                // Starts GET action
                answer = sendATcommand("AT+HTTPACTION=0", "+HTTPACTION:0,200", 30000);
                if (answer == 1)
                {

                    Serial.println(F("Done!"));
                }
                else
                {
                    Serial.println(F("Error getting url"));
                }

            }
            else
            {
                Serial.println(F("Error setting the url"));
            }
        }
        else
        {
            Serial.println(F("Error setting the CID"));
        }    
    }
    else
    {
        Serial.println(F("Error initializating"));
    }

    sendATcommand("AT+HTTPTERM", "OK", 5000);
    
}


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

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

    memset(response, '\0', 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){    
            response[x] = Serial.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;
}
    

Second step. When the GPS fix the GPS satellites, the GPRS+GPS shield will connect to the network and it will send the GPS data through the Internet to the php script in your computer.

Code:
<?php

    
if (!empty($_GET['latitude']) && !empty($_GET['longitude']) &&
        !empty(
$_GET['time']) && !empty($_GET['satellites']) &&
        !empty(
$_GET['speedOTG']) && !empty($_GET['course'])) {

        function 
getParameter($par$default null){
            if (isset(
$_GET[$par]) && strlen($_GET[$par])) return $_GET[$par];
            elseif (isset(
$_POST[$par]) && strlen($_POST[$par])) 
                return 
$_POST[$par];
            else return 
$default;
        }

        
$file 'gps.txt';
        
$lat getParameter("latitude");
        
$lon getParameter("longitude");
        
$time getParameter("time");
        
$sat getParameter("satellites");
        
$speed getParameter("speedOTG");
        
$course getParameter("course");
        
$person $lat.",".$lon.",".$time.",".$sat.",".$speed.",".$course."\n";
        
        echo 
"
            DATA:\n
            Latitude: "
.$lat."\n
            Longitude: "
.$lon."\n
            Time: "
.$time."\n
            Satellites: "
.$sat."\n
            Speed OTG: "
.$speed."\n
            Course: "
.$course;

        if (!
file_put_contents($file$personFILE_APPEND LOCK_EX))
            echo 
"\n\t Error saving Data\n";
        else echo 
"\n\t Data Save\n";
    }
    else {

?>

<!DOCTYPE html>
<html>
    
<head>

    <!-- Load Jquery -->

    <script language="JavaScript" type="text/javascript" src="jquery-1.10.1.min.js"></script>

    <!-- Load Google Maps Api -->

    <!-- IMPORTANT: change the API v3 key -->

    <script src="http://maps.googleapis.com/maps/api/js?key=your_key&sensor=false"></script>

    <!-- Initialize Map and markers -->

    <script type="text/javascript">
        var myCenter=new google.maps.LatLng(41.669578,-0.907495);
        var marker;
        var map;
        var mapProp;

        function initialize()
        {
            mapProp = {
              center:myCenter,
              zoom:15,
              mapTypeId:google.maps.MapTypeId.ROADMAP
              };
            setInterval('mark()',5000);
        }

        function mark()
        {
            map=new google.maps.Map(document.getElementById("googleMap"),mapProp);
            var file = "gps.txt";
            $.get(file, function(txt) { 
                var lines = txt.split("\n");
                for (var i=0;i<lines.length;i++){
                    console.log(lines[i]);
                    var words=lines[i].split(",");
                    if ((words[0]!="")&&(words[1]!=""))
                    {
                        marker=new google.maps.Marker({
                              position:new google.maps.LatLng(words[0],words[1]),
                              });
                        marker.setMap(map);
                        map.setCenter(new google.maps.LatLng(words[0],words[1]));
                        document.getElementById('sat').innerHTML=words[3];
                        document.getElementById('speed').innerHTML=words[4];
                        document.getElementById('course').innerHTML=words[5];
                    }
                }
                marker.setAnimation(google.maps.Animation.BOUNCE);
            });

        }

        google.maps.event.addDomListener(window, 'load', initialize);
    </script>
</head>

<body>
    <?php
        
echo '    

        <!-- Draw information table and Google Maps div -->

        <div>
            <center><br />
                <b> SIM908 GPS position DEMO </b><br /><br />
                <div id="superior" style="width:800px;border:1px solid">
                    <table style="width:100%">
                        <tr>
                            <td>Time</td>
                            <td>Satellites</td>
                            <td>Speed OTG</td>
                            <td>Course</td>
                        </tr>
                        <tr>
                            <td id="time">'
date("Y M d - H:m") .'</td>
                            <td id="sat"></td>
                            <td id="speed"></td>
                            <td id="course"></td>
                        </tr>
                </table>
                </div>
                <br /><br />
                <div id="googleMap" style="width:800px;height:700px;"></div>
            </center>
        </div>'
;
    
?>
</body>
</html>

<?php ?>

To use the php script you need an Apache server with php active. You can run the script in a PC installing Apache with php. You can do this easily with the installer from this pages ( or the package manger for linux):

In these websites, you have manuals to help you to install the server and active the php.

Extract the next php script on your computer. When a frame is received, a marker will shown in the map. You must change the Google Maps API v3 key in the php script: "http://maps.googleapis.com/maps/api/js?key=your_key&sensor=false"

To show the map with the marker you need to access to the next url:

http://your_IP_or_domain/demo_sim908.php

The IP address or server domain must be the same used in the skecth of arduino (In case you are running the demo on your computer, replace "your_IP_or_domain" by "localhost")

Download Demo files

Choosing the right cellular module for Arduino and Raspberry Pi: 4G / 3G / GPRS / GSM

Model
Protocols
Frequency Bands
Certifications
Market
SIM908 GPRS / GSM 850, 900, 1800, 1900MHz CE Europe
SIM5215-E 3G / GPRS / GSM 850, 900, 1800, 2100MHz CE, GCF Europe
SIM5215-A 3G / GPRS / GSM 850, 900, 1800, 1900MHz FCC, IC, PTCRB US / Canada
LE910-EU 4G / 3G / GPRS / GSM / WCDMA / HSPA+ / LTE 850, 900, 1800, 2100, 2600MHz CE, GCF, ANATEL Europe / Brasil
LE910-NAG 4G / 3G / GPRS / GSM / WCDMA / HSPA+ / LTE 700, 850, 900, 1700, 1900MHz FCC, IC, PTCRB, AT&T Compliant US / Canada
LE910-SKG 4G / LTE / HSPA+ 850, 1800MHz KCC South Korea
LE910-AU V2 4G / LTE / HSPA+ 850, 1500, 2100MHz RCM Australia
LE910-JN V2 4G / LTE / HSPA+ 850, 1500, 2100MHz NTT DoCoMo Japan
LE910-JK V2 4G / LTE / HSPA+ 850, 1500, 2100MHz KDDi Japan
Model
GPS
Camera Option
SD Card
USB Connnectivity
SIM908
Yes
No
No
No
SIM5215-E
No
Yes
Yes
Yes
SIM5215-A
No
Yes
Yes
Yes
LE910-EU
Yes
No
Yes
Yes
LE910-NAG
Yes
No
Yes
Yes
LE910-SKG
Yes
No
Yes
Yes
LE910-AU V2
Yes
No
Yes
Yes
LE910-JN V2
Yes
No
Yes
Yes
LE910-JK V2
Yes
No
Yes
Yes
Model
Download Max Speed
Upload Max Speed
Antenna Diversity
Cellular Carriers
SIM908
80kbps
20kbps
No
Any
SIM5215-E
384Kbps
384Kbps
No
Any
SIM5215-A
384Kbps
384Kbps
No
Any
LE910-EU
100Mbps
50Mbps
Yes
Any
LE910-NAG
100Mbps
50Mbps
Yes
Any + Specially tested with AT&T
LE910-SKG
100Mbps
50Mbps
Yes
Any + Specially tested with SK Telecom
LE910-AU V2
100Mbps
50Mbps
Yes
Any + Specially tested with Telstra
LE910-JN V2
100Mbps
50Mbps
Yes
Any + Specially tested with NTT DoCoMo
LE910-JK V2
100Mbps
50Mbps
Yes
Any + Specially tested with KDDi

Device Compatibility

This shield is tested and fully compatible with the following boards:

Arduino Boards

  • Arduino Uno

Raspberry Pi Boards

  • Raspberry Pi
  • Raspberry Pi (Model B+)
  • Raspberry Pi 2
  • Raspberry Pi 3