My Cart

3G + GPS shield over Arduino and Raspberry Pi

Difficulty Level: Expert -


The 3G shield for Arduino and Raspberry Pi enables the connectivity to high speed WCDMA and HSPA cellular networks in order to make possible the creation of the next level of worldwide interactivity projects inside the new "Internet of Things" era.

The module counts also with an internal GPS what enables the location of the device outdoors and indoors combining standard NMEA frames with mobile cell ID triangulation using both assisted-mobile (A-GPS) and mobile-based (S-GPS) modes.

Other interesting accessories which can be connected to the module are a 2MP high resolution camera (1600 x 1200) UXGA which enables take incredible photos and videos, an audio kit including microphone , speaker , hands free and headphones sets and a SD socket to save directly all the data coming from the 3G network or recorded from the video camera. You can even reproduce audio files stored in the SD card (like a mp3 player!).

You can also use it as a standard 3G modem at full speed (~7.2Mbps download, ~5.5Mbps upload) just connecting it through its specific mini-USB socket to your laptop (Linux, Windows, MacOS).

The new communicating module is specially oriented to work with Internet servers implementing internally several application layer protocols which make easier to send the information to the cloud. We can make HTTP and HTTPS (secure mode) navigation, downloading and uploading content to a web server. In the same way FTP and FTPS (secure mode) protocols are also available which is really useful when your application requires handling files. You can even send and receive mails directly from Arduino using the SMTP and POP3 clients implemented internally.

With the SD Card socket so you can handle a complete FAT16 file systems and store up to 32GB of information. This specially useful as the 3G module can work at full speed (~7.2Mbps download, ~5.5Mbps upload) when working with the SD files directly without need of Arduino for data or files management.

The GPS module also makes possible perform geolocation services even in indoors as it can work in A-GPS and S-GPS modes, so the location given by the GPS through NMEA sentences is completed with the cell information provided by both the 3G module and external Internet Geoposition Servers which helps you to get the most accurate location in each case.

Features

  • WCDMA and HSPA 3G networks compatibility
  • Internal GPS for Assisted A-GPS and Supported S-GPS modes
  • High Resolution Camera (2MP) for photo and video recordings available
  • Audio Kit including microphone, speaker, hands free and headphones available
  • SD file system up to 32GB
  • Works as a standard 3G modem in Linux/Windows/MacOS (~7.2Mbps download, ~5.5Mbps upload)
  • Talk directly to web servers by HTTP/HTTPS (secure)
  • Upload and download files directly by FTP/FTPS (secure)
  • Send and receive mails by POP3/SMTP
  • Play compressed audio files

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

NOTE: All the code examples in this tutorial developed for Raspberry Pi use the arduPi library. You can see the documentation and download the library here.

Kits and Accessories

Kits

Accesories

NOTE: the accessories (antennas, camera, microphone, speakers, headset, SD) are not included in the basic package. They may be acquired in any of the multi kits or by separate.

NOTE: If you only need to send SMS or use a low bandwidth for data transfer you can use our cheaper GPRS/GSM Quadband SIM900 module for Arduino and Raspberry Pi.

Does make sense a 3G module for a low speed microcontroller device such as Arduino?

Definitively yes.

On the one hand you can use the Arduino UART at full speed ~ 115kbps, so the communication of data will be at the same bandwidth as if you had the Arduino connected directly to the USB directly (obviously with more initial latency). With the GPRS modules available in the market until now the speed limit was established by the GPRS network ~ 20kbps, so now we get 6 times more download performance than before. The upload speed the increment three times from 10kbps (GPRS) to 35kbps (3G).

On the other hand there is a bunch of actions can be made directly from the 3G module without having to go through the Arduino microcontroller. This means you will control all the action from the main program running in Arduino although the data may flow from the 3G module to the SD card or from the video camera to the 3G module without going through the UART avoiding a possible bottle neck and ensuring maximum speed performance given by your 3G carrier (~7.2Mbps download, ~5.5Mbps upload at max). Some of this independent actions include:

  • Uploading and downloading files to HTTP and FTP servers directly from or to the SD
  • Recording and uploading video and photos to the Internet using the video camera connected directly to the module
  • Recording ambient audio and sending to a web server

This files may be also stored in the SD card of the 3G and in order to manage them after.

As well as this, the module offers theoretically also the possibility of performing Video-Calls. We say "theoretically" as the tests performed in Cooking Hacks we got a carrier error, the same we got when trying to make a Video-Call with our Smartphones so, although everything points it is is a carrier problem we can not ensure the Video-Call functionality (if you get please let us know!).

As pointed before the 3G module can also be used as and standalone 3G/GPRS USB modem! It works in Linux, Windows and MacOS, just plug it through its specific USB connector to your laptop and follow the steps located in the current manual.

You can control also the kind of network service and the quality of the signal received (RSSI) from the surrounding cells you are using even change among them: GSM - GPRS - WCDMA - HSPA depending on the coverage of the zone. Get detailed information about the frequency band you are using to connect to the carrier and the quality of the signal.

Article Index

1. Features

Electrical features

The 3G module used is the SIM5218 from SIMCOM. The power supply of SIM5218 is from a single voltage source of VBAT= 3.4v-4.2v. In some case, the ripple in a transmit burst may cause voltage drops when current consumption rise to typical peaks of 2A. So the power supply must be able to provide sufficient current up to 2A. The maximum rating are VBAT=4,4v and 3A peak. The maximum value of voltage for digital or analogy pins is 2.8v.

Radio features

SIM5218 is a quad-band GSM/GPRS/EDGE and UMTS engine that works on frequencies of GSM 850MHz, EGSM 900 MHz, DCS 1800 MHz, PCS1900 MHz, and WCDMA 2100M/1900M/850M.

Output power:

  • UMTS 850/900/1900/2100: 0.25W
  • GSM850/GSM900: 2W
  • DCS1800/PCS1900: 1W

NOTE: when flight mode is activated RF functions are closed. The mode can be changed by putting the jumper in position (see 3G shield diagram below).

NOTE FOR US USERS: We have tested the new 3G shield with the AT&T network which supports nativelly the GSM and 3G protocolos. With other carriers may also work although we haven't tried and thus we can not ensure it. For this reason we recommend to use AT&T SIM cards.

Extra features

  • USIM interface: support SIM cards: 3V & 1.8V
  • High speed USB interface for modem
  • Three audio channels include two microphones inputs and three audio outputs.
  • A camera interface is provided in FPC connector and 2mm pitch holes.
  • I2C interface is provided.
  • 8-bit ADC input with an input voltage range between 2.65v and GND
  • 2.8v LDO power output
  • 4 bit microSD card interface
  • 3 modes of GPS (stand alone, S-GPS y A-GPS)
  • FTP and FTPS for managing files
  • TCP and UDP sockets
  • POP3 and SMTP for e-mail

2. Hardware

3G Shield diagram

Version 2 of the shield:

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 3G shield

Version 1 of the shield:

3G Shield PCB

Version 2 of the shield:

Version 1 of the shield:

3. Antennas

Connections

SIM5218 has 3 UFL connectors. Two for diversity of 3G mobile carriers and one for GPS antenna. The impedance of the RF interface is 50Ω. It is recommended use just the "main" antenna socket for the mobile connection unless you experience coverage or performance problems. In this case two antennas allowing diversity may be placed.

Also, the module allows to solder the antenna to the pad, or attach it via contact springs.

Antenna availability

We recommend the usage of the following antennas:

4. Bandwidth

3G module connected with Arduino allows downlinks rates over 115200 bauds (~11.5KBps), the maximum UART's speed and uplinks rates over 30000 bauds (~3KBps). Using the module as 3G USB modem we got speeds of 2Mbps (~222KBps) for downlink and 0.7Mbps (~77KBps) for uplink and. The connection speed may vary depending on the state of the network, the quality of the signal and the carrier.

5. Using 3G 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 or Raspberry Pi, the power jumper must be in Arduino 5V position. If the shield is powered from the Vin input (in the shield), the power jumper must be in Vext position.

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

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

NOTE: If your 3G module doesn't answer to AT commands, maybe it is configured in a different baudrate. The command for change it temporally is AT+IPR. Try differents baudrates (300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800,921600, 3200000,3686400,4000000 ) until you get to communicate. Once you can communicate, you can configure it in the baudrate you want.

Using 3G 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.

Basic configuration:

Connect the shield to the Arduino gateway.

Then connect the SIM card and the USB cable.

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.

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 400
#define SERIAL_RX_BUFFER_SIZE 400
#else
#define SERIAL_TX_BUFFER_SIZE 400
#define SERIAL_RX_BUFFER_SIZE 400
#endif
#endif
                

Using 3G 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 3G shield to the right, in RPI position.
  2. Place the two Serial com. jumpers in the 3G 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 left, 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 of 5V or 12V you must place it through the Vin pin, (in the shield, it is placed where Arduino has the Vin pin), the “Vin ext. jumper” must be set to the right, in “Vin position”. The power supply must be able to provide sufficient current up to 2A. 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 shield to the Raspberry Pi connection bridge and the antennas to the shield. 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.

6. Using 3G module like a modem

If you want to use the 3G module such a modem, please refer to the next link:

3G modem tutorial

7. Audio

Audio features

SIM5218 module provides two analogy inputs for microphone and three analogy outputs for two speakers and headphones. Depending of the selected audio channel (normal, headset and hands-free) a specific input and output are activated. The different channels are selected with the command AT+CSDVC.

Normal channel (AT+CSDVC=1) uses the main microphone and a speaker. Headset channel (AT+CSDVC=2) uses the jack connector. Hand-free channel (AT+CSDVC=3) uses the main microphone and the loudspeaker.

Both microphones don't need an external power source because they are powered directly by the module. You can use some extra commands in your codes like noise suppression, echo canceller or the gain of the mic amps. Please, refer to the AT command document list at the end of this article for more information.

Audio connectors

Audio connectors are situated at the bottom of the board. The two speakers and the main microphone are connected to board using pin connectors.

3G/GPRS shield for Arduino (3G + GPS) + Audio/Video Kit

Headset connector are situated at the bottom too, between Arduino board and 3G board.

This connector has 4 terminals that correspond with the positive terminal of the microphone, left and rigth headphones and common ground. The order of connections show below.

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:
/*
 *  Description: This example does a call and hangs it when a button has pressed.
 *  This example only shows the AT commands (and the answers of the module) used
 *  to do a call. For more information about the AT commands, refer to the AT
 *  command manual.
 *
 *  Copyright (C) 2013 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.
 *
 *  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 0.2
 *  Author: Alejandro Gallego & Victor Boria
 */


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

//Change here your data
const char pin[] = "****";
const char phone_number[] = "*********";   // ********* is the number to call


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...");

  //Enables the use of command ATH
  sendATcommand("AT+CVHU=0", "OK", 10000);

  while ( (sendATcommand("AT+CREG?", "+CREG: 0,1", 500) ||
           sendATcommand("AT+CREG?", "+CREG: 0,5", 500)) == 0 );
  
  Serial.print("Calling to ");
  Serial.print(phone_number);
  Serial.println("...Press button to hang");

  
  //Make the phone call
  sprintf(aux_str, "ATD%s;", phone_number);
  sendATcommand(aux_str, "OK", 10000);

  // press the button for hang the call
  while (digitalRead(button) == 1);
  
  // disconnects the existing call
  Serial.println("ATH");            
  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 (Serial.available() != 0) {
      // if there are data in the UART input buffer, reads it and checks for the answer
      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 answer with time out
  } while ((answer == 0) && ((millis() - previous) < timeout));

  return answer;
}

        

Raspberry Pi:

Code:
/*
 *  Description: This example does a call and hangs it when a button has pressed.
 *  This example only shows the AT commands (and the answers of the module) used
 *  to do a call. For more information about the AT commands, refer to the AT
 *  command manual.
 *
 *  Copyright (C) 2012 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.
 *
 *  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
 *  Author: Alejandro Gállego & Victor Boria
 */

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

//Change here your data
const char pin[] = "****";
const char phone_number[] = "*********";   // ********* is the number to call

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

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

int button = 12;

void setup() {

  pinMode(onModulePin, OUTPUT);
  pinMode(button, INPUT);
  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");

  //Enables the use of command ATH
  sendATcommand("AT+CVHU=0", "OK", 10000);

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

  //Make the call
  sprintf(aux_str, "ATD%s;", phone_number);
  sendATcommand(aux_str, "OK", 10000);

  printf("Calling to %s...Press button to hang\n", phone_number);

  // 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_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();
      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;
}




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

        

To make a lost call next code is used.

Arduino:

Code:
/*
 *  Description: This example does a lostcall. This example only shows the AT
 *  commands (and the answers of the module) used to do a lostcall. For more
 *  information about the AT commands, refer to the AT command manual.
 *
 *  Copyright (C) 2013 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.
 *
 *  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 0.2
 *  Author: Alejandro Gallego & Victor Boria
 */

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

//Change here your data
const char pin[] = "****";
char phone_number[] = "*********";   // ********* is the number to call
int seconds = 20;

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...");

  //Enables the use of command ATH
  sendATcommand("AT+CVHU=0", "OK", 10000);
  
  while ( (sendATcommand("AT+CREG?", "+CREG: 0,1", 500) ||
           sendATcommand("AT+CREG?", "+CREG: 0,5", 500)) == 0 );

  
  Serial.print("Calling to ");
  Serial.println(phone_number);

  //Make the phone call
  sprintf(aux_str, "ATD%s;", phone_number);
  sendATcommand(aux_str, "OK", 10000);

  delay(seconds * 1000);
  
  // disconnects the existing call
  Serial.println("ATH");            
  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 answer
    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 answer with time out
  } while ((answer == 0) && ((millis() - previous) < timeout));

  return answer;
}

        

Raspberry Pi:

Code:
/*
 *  Description: This example does a lostcall. This example only shows the AT
 *  commands (and the answers of the module) used to do a lostcall. For more
 *  information about the AT commands, refer to the AT command manual.
 *
 *  Copyright (C) 2012 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.
 *
 *  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
 *  Author: Alejandro Gállego & Victor Boria
 */

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

//Change here your data
const char pin[] = "****";
const char phone_number[] = "*********";   // ********* is the number to call
int seconds = 20;

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

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


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

  //Enables the use of command ATH
  sendATcommand("AT+CVHU=0", "OK", 10000);

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

  //Make the call
  sprintf(aux_str, "ATD%s;", phone_number);
  sendATcommand(aux_str, "OK", 10000);

  printf("Calling to %s...Waiting %d seconds\n", phone_number, seconds);

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




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.

Arduino:

Code:
/*
 *  Description: This example does a lostcall. This example only shows the AT
 *  commands (and the answers of the module) used to do a lostcall. For more
 *  information about the AT commands, refer to the AT command manual.
 *
 *  Copyright (C) 2013 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.
 *
 *  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
 *  Author: Alejandro Gallego & Victor Boria
 */


//Change here your data
const char pin[] = "****";

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


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


  //Enables the use of command ATH
  sendATcommand("AT+CVHU=0", "OK", 10000);

  delay(3000);

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

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

}

void loop() {

  answer = sendATcommand("", "RING", 1000);
  if (answer == 1)
  {
    Serial.println("Incoming call");

    // press the button for hang the call
    while (digitalRead(button) == 1);

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


}

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 answer
    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 answer with time out
  } while ((answer == 0) && ((millis() - previous) < timeout));

  return answer;
}

        

Raspberry Pi:

Code:
/*
 *  Description: This example does a lostcall. This example only shows the AT
 *  commands (and the answers of the module) used to do a lostcall. For more
 *  information about the AT commands, refer to the AT command manual.
 *
 *  Copyright (C) 2012 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.
 *
 *  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
 *  Author: Alejandro Gállego & Victor Boria
 */

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

//Change here your data
const char pin[] = "****";

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

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

int button = 12;


void setup() {

  pinMode(onModulePin, OUTPUT);
  pinMode(button, INPUT);
  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");

  //Enables the use of command ATH
  sendATcommand("AT+CVHU=0", "OK", 10000);

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


  printf("Waiting for a call\n");
}

void loop() {

  answer = sendATcommand("", "RING", 1000);
  if (answer == 1)
  {

    printf("Incoming call\n");

    // press the button for hang the call
    while (digitalRead(button) == 1);

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


  }
}





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

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




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

        

The channel may be changed during a call. Use the command AT+CSDVC to select the channel that you want.

Recording and playing sound

With the next code we can record a sound, stores it and before play it. You can select the place to store the sound clip: the local storage or a SD card. Once saved the sound can be sent to an FTP or FTPS as you'll see later.

Arduino:

Code:
/*
 *  Description: This example shows how to record sound from the microphone
 *  and then play the file with the sound recorded.
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with audio commands. For more information about the AT commands, 
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2013 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. 
 *  
 *  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 0.2
 *  Author: Alejandro Gallego & Victor Boria 
 */


int8_t answer, counter;
int onModulePin = 2;
char clip_name[20];
char aux_str[50];

void setup(){

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

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

  //Starts recording sound clips
  Serial.println("Recording sound clip");

  answer = sendATcommand2("AT+CQCPREC=0,amr", "C:/Audio/", "ERROR", 5000);
  if (answer == 1)
  {
    counter = 0;
    while(Serial.available()==0);
    do{
      clip_name[counter] = Serial.read();
      counter++;
      while(Serial.available()==0);
    }
    while (clip_name[counter-1] != 0x0D);

    clip_name[counter-1] = '\0';

    Serial.print("Clip name: ");                
    Serial.println(clip_name);
    delay(5000);
    sendATcommand2("AT+CQCPPAUSE", "OK", "ERROR", 2000);
    delay(5000);            
    sendATcommand2("AT+CQCPRESUME", "OK", "ERROR", 2000);
    delay(5000);            
    sendATcommand2("AT+CQCPSTOP", "OK", "ERROR", 2000);

    sendATcommand2("AT+FSCD=C:/Audio", "OK", "ERROR", 2000);
    sprintf(aux_str, "AT+CCMXPLAY=\"%s\",0", clip_name);
    answer = sendATcommand2(aux_str, "OK", "ERROR", 2000);
    if (answer == 1)
    {            
      delay(5000);
      sendATcommand2("AT+CCMXPAUSE", "OK", "ERROR", 2000);
      delay(5000);            
      sendATcommand2("AT+CCMXRESUME", "OK", "ERROR", 2000);
      delay(5000);            
      sendATcommand2("AT+CCMXSTOP", "OK", "ERROR", 2000);
    }
    else
    {
      Serial.println("Error playing");    
    }
  }
  else
  {
    Serial.println("Error recording");    
  }


}
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_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 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_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 there are data in the UART input buffer, reads it and checks for the answer
    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 answer with time out
  }
  while((answer == 0) && ((millis() - previous) < timeout));    

  return answer;
}

        

Raspberry Pi:

Code:
/*
 *  Description: This example shows how to record sound from the microphone
 *  and then play the file with the sound recorded.
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with audio commands. For more information about the AT commands,
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2012 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.
 *
 *  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
 *  Author: Alejandro Gállego & Victor Boria
 */

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

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

int8_t answer, counter;
int onModulePin = 2;
char aux_str[50];
char clip_name[20];

void setup()
{

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

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

  delay(3000);


  //Starts recording sound clips
  printf("Recording sound clip\n");

  answer = sendATcommand2("AT+CQCPREC=0,amr", "C:/Audio/", "ERROR", 5000);
  if (answer == 1)
  {
    counter = 0;
    while (Serial.available() == 0);
    do {
      clip_name[counter] = Serial.read();
      counter++;
      while (Serial.available() == 0);
    }
    while (clip_name[counter - 1] != 0x0D);

    clip_name[counter - 1] = '\0';

    printf("Clip name: %s\n", clip_name );
    delay(5000);
    sendATcommand2("AT+CQCPPAUSE", "OK", "ERROR", 2000);
    delay(5000);
    sendATcommand2("AT+CQCPRESUME", "OK", "ERROR", 2000);
    delay(5000);
    sendATcommand2("AT+CQCPSTOP", "OK", "ERROR", 2000);

    sendATcommand2("AT+FSCD=C:/Audio", "OK", "ERROR", 2000);
    sprintf(aux_str, "AT+CCMXPLAY=\"%s\",0", clip_name);
    answer = sendATcommand2(aux_str, "OK", "ERROR", 2000);
    if (answer == 1)
    {
      delay(5000);
      sendATcommand2("AT+CCMXPAUSE", "OK", "ERROR", 2000);
      delay(5000);
      sendATcommand2("AT+CCMXRESUME", "OK", "ERROR", 2000);
      delay(5000);
      sendATcommand2("AT+CCMXSTOP", "OK", "ERROR", 2000);
    }
    else
    {
      printf("Error playing\n");
    }
  }
  else
  {
    printf("Error recording\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_answer1, unsigned int timeout)
{

  uint16_t x = 0,  answer = 0;
  char response[1000];
  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();
      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);

  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();
      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 answer with time out
  }
  while ((answer == 0) && ((millis() - previous) < timeout));

  return answer;
}


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

        

Also, you can use the 3G module like a mp3 player! First, you must save your music in mp3, amr or qcp format. You can use Audacity (linux) or Mobile Media Converter (Windows or Linux) to do this. Then, save the music in the Audio folder on microSD card. Now, put microSD card into the shield and enjoy the music!

NOTE: You will need to update your firmware to play mp3. The update is available here. Uncompress and run it in a PC with Windows (emulated Windows not supported).

A voice call can be recorded using these same commands too.

Command summary

Command Response Description
AT+CPTONE=** OK Plays a DTMF tone or complex tone on local voice channel device . ** is the number of the tone.
ATD*********;   ********* is the number to call.
ATA OK Answer an incoming call.
AT+CHUP OK Cancel voice calls.
AT+CNSM OK Enable/disable noise suppression.
AT+CQCPREC=*,&&&   Starts recording sound clips . Answers with the path and the name of the clip. * is the path and &&& is the format.
AT+CQCPPAUSE OK Pauses record sound.
AT+CQCPRESUME OK Resumes record sound.
AT+CQCPSTOP OK Stops record sound.
AT+CCMXPLAY=”*****” OK Plays an audio file . ***** is the name of the file.
AT+CCMXPAUSE OK Pauses playing audio file.
AT+CCMXRESUME OK Resumes playing audio file.
AT+CCMXSTOP OK Stops playing audio file.

8. Camera

We have modified the 3G Shield to make it work with a better camera. So instead of using the old 0'3MP Camera, now the shield supports a 2MP Camera, improving the resolution from 640 x 480 (VGA) to 1600 x 1200 (UXGA)!

Comparative:

Old Camera New Camera
Resolution 0.3 MP 2 MP
Sensor OV7725 OV2640
Max. resolution 640 x 480 (VGA) 1600 x 1200 (UXGA)
Image area 3984 µm x 2952 µm 3590 µm x 2684 µm
Sensitivity 3800 mV/Lux-sec 0.6 V/Lux-sec
Optical format 1/4" 1/4"
Power 120 mW 140 mW

Click in the next photos to enlarge (left click):

Old photo

New photo

The new 2MP Camera is included in the Audio / Video 3G Kit. You can also get directly the 2MP Camera here.

NOTE: The new 2MP Camera can be used only in the last version of the 3G Shield. The old 0'3MP camera can not be used in the new version of the 3G Shield.

NOTE: The 2MP resolution of 1600 x 1200 is just for photos. Video recording is performed at 320 x 240 due to module restrictions.

How do I know if my 3G Shield is compatible with the new 2MP Camera?

  • Check your serial ID. The sticker included in the shield tells you the number of batch. The new 2MP Camera is compatible with batches xxxx-0010-xxx and above.
  • Date of Order. For orders starting in June 2014 all the 3G Shields sold are compatible with the new 2MP Camera.

Camera features

This module allows to connect a camera for video recording and taking photos. Once saved the video or image file can be sent to an FTP or FTPS as you'll see later. The pin diagram shows below:

Pin nº Name Pin nº Name Pin nº Name
1 NC 9 HSYNC 17 PCLK
2 AGND 10 DVDD 18 DATA6
3 SDA 11 DOVDD 19 DATA2
4 AVDD 12 DATA9 20 DATA5
5 SCL 13 MCLK 21 DATA3
6 RESET 14 DATA8 22 DATA4
7 VSYNC 15 AGND 23 DATA1
8 PWDN 16 DATA7 24 DATA0

Mounting the camera

Follow these simple steps to mount the camera into the 3G Arduino board.

The first step is to open the socket. To do this, pull carefully out the sides of the connector.

Inserts the camera with metallic contacts facing up

At the final step, push in the laterals of the connector.

The camera may get hot if continuous usage is performed. Maximum operation temperature is 45ÂşC.

Video recording

To record video, and take images, you must start the camera in the first step. After you can configure some parameters like resolution, fps, rotation or zoom. The next code allows to record a video file in mp4 format. Remember, if you want to store the video file in a SD card, you must to use AT+FSLOCA command.

Arduino:

Code:
/*
 *  Description: This example shows how to record a video from the camera
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with the camera. For more information about the AT commands, 
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2013 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. 
 *  
 *  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 0.2
 *  Author: Alejandro Gallego & Victor Boria
 */


int8_t answer;
int onModulePin= 2;

void setup(){

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

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

  delay(3000);

  // Starts the camera
  answer = sendATcommand2("AT+CCAMS", "OK", "CAMERA NO SENSOR", 3000);
  if (answer == 1)
  {
    // Sets resolution
    sendATcommand2("AT+CCAMSETD=320,240", "OK", "ERROR", 2000);

    // Sets frame rate
    sendATcommand2("AT+CCAMSETF=2", "OK", "ERROR", 2000);

    // Takes a picture, but not saved it
    answer = sendATcommand2("AT+CCAMRS", "OK", "ERROR", 5000);
    delay(1000);
    if (answer == 1)
    {
      delay(5000);
      sendATcommand2("AT+CCAMRP", "OK", "ERROR", 2000);
      delay(5000);            
      sendATcommand2("AT+CCAMRR", "OK", "ERROR", 2000);
      delay(5000);            
      sendATcommand2("AT+CCAMRE", "OK", "ERROR", 2000);

    }
    else if (answer == 2)
    {
      Serial.println("Camera invalid state");    
    }
    else
    {
      Serial.println("Error taking the picture");    
    }

    sendATcommand("AT+CCAME", "OK", 2000);   
  }
  else if (answer == 2)
  {
    Serial.println("Camera not detected");    
  }
  else
  {
    Serial.println("Error starting the camera");    
  }



}
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_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 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_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 there are data in the UART input buffer, reads it and checks for the answer
    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 answer with time out
  }
  while((answer == 0) && ((millis() - previous) < timeout));    

  return answer;
}

        

Raspberry Pi:

Code:
/*
 *  Description: This example shows how to record a video from the camera
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with the camera. For more information about the AT commands,
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2012 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.
 *
 *  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
 *  Author: Alejandro Gállego & Victor Boria
 */

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

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

int8_t answer;
int onModulePin = 2;


void setup()
{

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

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

  delay(3000);


  // Starts the camera
  answer = sendATcommand2("AT+CCAMS", "OK", "CAMERA NO SENSOR", 3000);
  if (answer == 1)
  {
    // Sets resolution
    sendATcommand2("AT+CCAMSETD=320,240", "OK", "ERROR", 2000);

    // Sets frame rate
    sendATcommand2("AT+CCAMSETF=2", "OK", "ERROR", 2000);

    // Takes a picture, but not saved it
    answer = sendATcommand2("AT+CCAMRS", "OK", "ERROR", 5000);
    delay(1000);
    if (answer == 1)
    {
      delay(5000);
      sendATcommand2("AT+CCAMRP", "OK", "ERROR", 2000);
      delay(5000);
      sendATcommand2("AT+CCAMRR", "OK", "ERROR", 2000);
      delay(5000);
      sendATcommand2("AT+CCAMRE", "OK", "ERROR", 2000);

    }
    else if (answer == 2)
    {
      printf("Camera invalid state\n");
    }
    else
    {
      printf("Error taking the picture\n");
    }

    sendATcommand("AT+CCAME", "OK", 2000);
  }
  else if (answer == 2)
  {
    printf("Camera not detected\n");
  }
  else
  {
    printf("Error starting the camera\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_answer1, unsigned int timeout)
{

  uint16_t x = 0,  answer = 0;
  char response[1000];
  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();
      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);

  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();
      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 answer with time out
  }
  while ((answer == 0) && ((millis() - previous) < timeout));

  return answer;
}


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

Taking photos

Take photos is very easy, here is the example code:

Arduino:

Code:
/*
 *  Description: This example shows how to take a picture from the camera
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with the camera. For more information about the AT commands, 
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2013 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. 
 *  
 *  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 0.3
 *  Author: Alejandro Gallego & Victor Boria
 */


int8_t answer, counter;
int onModulePin = 2;
char picture_name[20];

void setup(){

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

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

  delay(5000);

  // Starts the camera
  answer = sendATcommand2("AT+CCAMS", "OK", "CAMERA NO SENSOR", 3000);
  if (answer == 1)
  {
    // Sets resolution (Old camera)
    //sendATcommand2("AT+CCAMSETD=640,480", "OK", "ERROR", 2000);

    // Sets resolution (New camera)
    sendATcommand2("AT+CCAMSETD=1600,1200", "OK", "ERROR", 2000);

    // Takes a picture, but not saved it
    answer = sendATcommand2("AT+CCAMTP", "OK", "ERROR", 5000);
    delay(1000);
    if (answer == 1)
    {
      // Saves the picture into C:/Picture
      answer = sendATcommand2("AT+CCAMEP", "C:/Picture/", "ERROR", 2000);

      if (answer == 1)
      {
        counter = 0;
        while(Serial.available()==0);
        do{
          picture_name[counter] = Serial.read();
          counter++;
          while(Serial.available()==0);
        }
        while (picture_name[counter-1] != 0x0D);

        picture_name[counter] = '\0';

        Serial.print("Picture name: ");                
        Serial.println(picture_name);

        sendATcommand("AT+CCAME", "OK", 2000);            

      }
      else
      {
        Serial.println("Error saving the picture");    
      }  
    }
    else if (answer == 2)
    {
      Serial.println("Camera invalid state");    
    }
    else
    {
      Serial.println("Error taking the picture");    
    }
  }
  else if (answer == 2)
  {
    Serial.println("Camera not detected");    
  }
  else
  {
    Serial.println("Error starting the camera");    
  }



}
void loop(){

}

void power_on(){

  uint8_t 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_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 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_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 there are data in the UART input buffer, reads it and checks for the answer
    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 answer with time out
  }
  while((answer == 0) && ((millis() - previous) < timeout));    

  return answer;
}

        

Raspberry Pi:

Code:
/*
 *  Description: This example shows how to take a picture from the camera
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with the camera. For more information about the AT commands,
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2012 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.
 *
 *  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
 *  Author: Alejandro Gállego & Victor Boria
 */

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

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

int8_t answer, counter;
int onModulePin = 2;
char picture_name[20];

void setup()
{

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

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

  delay(3000);


  // Starts the camera
  answer = sendATcommand2("AT+CCAMS", "OK", "CAMERA NO SENSOR", 3000);
  if (answer == 1)
  {
    // Sets resolution (Old camera)
    //sendATcommand2("AT+CCAMSETD=640,480", "OK", "ERROR", 2000);

    // Sets resolution (New camera)
    sendATcommand2("AT+CCAMSETD=1600,1200", "OK", "ERROR", 2000);

    // Sets SD as storage place
    sendATcommand2("AT+FSLOCA=1", "OK", "ERROR", 2000);

    // Takes a picture, but not saved it
    answer = sendATcommand2("AT+CCAMTP", "OK", "ERROR", 5000);
    delay(1000);
    if (answer == 1)
    {
      // Saves the picture into D:/Picture (SD)
      answer = sendATcommand2("AT+CCAMEP", "D:/Picture/", "ERROR", 2000);

      if (answer == 1)
      {
        counter = 0;
        while (Serial.available() == 0);
        do {
          picture_name[counter] = Serial.read();
          counter++;
          while (Serial.available() == 0);
        } while (picture_name[counter - 1] != 0x0D);

        picture_name[counter] = '\0';

        printf("Picture name: %s\n", picture_name);

        sendATcommand2("AT+CCAME", "OK", "", 2000);

      }
      else
      {

        printf("Error saving the picture\n");
      }
    }
    else if (answer == 2)
    {
      printf("Camera invalid state\n");
    }
    else
    {
      printf("Error taking the picture\n");
    }
  }
  else if (answer == 2)
  {
    printf("Camera not detected\n", picture_name);
  }
  else
  {
    printf("Error starting the camera\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_answer1, unsigned int timeout)
{

  uint16_t x = 0,  answer = 0;
  char response[1000];
  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();
      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);

  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();
      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 answer with time out
  }
  while ((answer == 0) && ((millis() - previous) < timeout));

  return answer;
}


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

        

Video call

The SIM5218 allows video calls, but to carry them out correctly the operator and the network must be able to allow it. The example code is below. Cooking Hacks not ensure that the video call functions correctly.

Please, be sure that your SIM card have activated the videocall feature, with your network operator and with the phone that you want to call, before to test the next sketch.

Arduino:

Code:
/*
 *  Description: This example does a videocall of 20 seconds.
 *  This example only shows the AT commands (and the answers of the module) used
 *  to do a videocall. For more information about the AT commands, refer to the AT 
 *  command manual.
 *
 *  Copyright (C) 2013 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. 
 *  
 *  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 0.2
 *  Author: Alejandro Gallego & Victor Boria
 */


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

//Change here your data
const char pin[]="****";
char phone_number[]="*********";     // ********* is the number to call

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(sendATcommand2("AT+CREG?", "+CREG: 0,1", "+CREG: 0,5", 1000) == 0 );


  // Starts the camera
  answer = sendATcommand2("AT+CCAMS", "OK", "CAMERA NO SENSOR", 3000);
  if (answer == 1)
  {
    // Sets resolution
    sendATcommand2("AT+CCAMSETD=320,240", "OK", "ERROR", 2000);

    sprintf(aux_str, "AT+VPMAKE=%s", phone_number);
    answer = sendATcommand2(aux_str, "VPCONNECTED", "VPEND", 30000);
    if (answer == 1)
    {
      delay(20000);
      sendATcommand("AT+VPEND", "OK", 30000);
    }
    else
    {
      Serial.println("Error originating the call");    
    }
  }
  else if (answer == 2)
  {
    Serial.println("Camera not detected");    
  }
  else
  {
    Serial.println("Error starting the camera");    
  }

}


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

  // 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 expected answer 1 is in the response of the module
      if (strstr(response, expected_answer1) != NULL)    
      {
        answer = 1;
      }
      // check if the expected answer 2 is in the response of the module
      if (strstr(response, expected_answer2) != NULL)    
      {
        answer = 2;
      }
    }
    // Waits for the answer with time out
  }
  while((answer == 0) && ((millis() - previous) < timeout));    

  return answer;
}
        

Raspberry Pi:

Code:
/*
 *  Description: This example does a videocall of 20 seconds.
 *  This example only shows the AT commands (and the answers of the module) used
 *  to do a videocall. For more information about the AT commands, refer to the AT
 *  command manual.
 *
 *  Copyright (C) 2012 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.
 *
 *  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
 *  Author: Alejandro Gállego & Victor Boria
 */

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

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

//Change here your data
const char pin[] = "****";
const char phone_number[] = "*********";   // ********* is the number to call

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

void setup()
{

  pinMode(onModulePin, OUTPUT);
  pinMode(button, INPUT);
  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");

  //Enables the use of command ATH
  sendATcommand("AT+CVHU=0", "OK", 10000);

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


  // Starts the camera
  answer = sendATcommand2("AT+CCAMS", "OK", "CAMERA NO SENSOR", 3000);
  if (answer == 1)
  {
    // Sets resolution
    sendATcommand2("AT+CCAMSETD=320,240", "OK", "ERROR", 2000);

    sprintf(aux_str, "AT+VPMAKE=%s", phone_number);
    answer = sendATcommand2(aux_str, "VPCONNECTED", "VPEND", 30000);
    if (answer == 1)
    {
      delay(20000);
      sendATcommand("AT+VPEND", "OK", 30000);
    }
    else
    {
      printf("Error originating the call\n");
    }
  }
  else if (answer == 2)
  {
    printf("Camera not detected\n");
  }
  else
  {
    printf("Error starting the camera\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_answer1, unsigned int timeout)
{

  uint16_t x = 0,  answer = 0;
  char response[1000];
  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();
      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);

  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();
      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 answer 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+CCAMS OK Starts camera.
AT+CCAME OK Stops camera.
AT+CCAMSETD=xxx,yyy OK Sets dimension of camera. xxx is the width and yyy is the height.
AT+CCAMSETF=* OK Sets the frames per second. * is the frame rate option.
AT+CCAMRS OK Starts video recording . Also responds with the path and name of the file.
AT+CCAMRP OK Pauses the record.
AT+CCAMRR OK Resumes video record.
AT+CCAMRE OK Stops video record.
AT+CCAMTP OK Takes a picture.
AT+CCAMEP OK Saves a picture taken by last AT+CCAMTP. Also responds with the path and name of the file.
AT+VPMAKE   Makes a video call.
AT+VPEND   Ends a video call.

9. GPS

SIM5218 supports both A-GPS and S-GPS and provides three operating modes: mobile-assisted mode, mobile-based mode and standalone mode. A-GPS is include mobile-assisted and mobile-based mode.

In mobile-assisted mode, when a request for position location is issued, available network information is provided to the location server (e.g., Cell-ID) and assistance is requested from the location server. The location server sends the assistance information to the handset. The handset/mobile unit measures the GPS observables and provides the GPS measurements along with available network data (that is appropriate for the given air interface technology) to the location server. The location server then calculates the position location and returns results to the requesting entity.

In mobile-based mode, the assistance data provided by the location server encompasses not only the information required to assist the handset in measuring the satellite signals, but also the information required to calculate the handset’s position. Therefore, rather than provide the GPS measurements and available network data back to the location server, the mobile calculates the location on the handset and passes the result to the requesting entity.

In standalone (autonomous) mode, the handset demodulates the data directly from the GPS satellites. This mode has some reduced cold-start sensitivity, and a longer time to first fix as compared to the assisted modes. However, it requires no server interaction and works out of network coverage.

This combination of GPS measurements and available network information provides:

  • High-sensitivity solution that works in all terrains: indoor, outdoor, urban, and rural
  • High availability that is enabled by using both satellite and network information

Therefore, while network solutions typically perform poorly in rural areas and areas of poor cell geometry/density, and while unassisted, GPS-only solutions typically perform poorly indoors, the SIM5218 GPS solution provides optimal time to fix, accuracy, sensitivity, availability, and reduced network utilization in both of these environments, depending on the given condition.

Stand-alone mode

In this mode, the GPS obtains position, altitude,... with only the signal of the satellites, making it the slowest of the three modes. If you use the AT+CGPSINFO command, the module bring directly latitud, logitude, date, UTC time, altitude and speed. Here is the example code:

Arduino:

Code:
/*
 *  Description: This example shows how to use the stand-alone GPS
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with the stand-alone GPS. For more information about the AT commands, 
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2013 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. 
 *  
 *  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 0.2
 *  Author: Alejandro Gallego & Victor Boria
 */


int8_t answer;
int onModulePin= 2;
char gps_data[100];
int counter;

void setup(){

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

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

  delay(5000);

  // starts GPS session in stand alone mode
  answer = sendATcommand("AT+CGPS=1,1","OK",1000);    
  if (answer == 0)
  {
    Serial.println("Error starting the GPS");
    Serial.println("The code stucks here!!");
    while(1);
  }
}


void loop(){

  answer = sendATcommand("AT+CGPSINFO","+CGPSINFO:",1000);    // request info from GPS
  if (answer == 1)
  {

    counter = 0;
    do{
      while(Serial.available() == 0);
      gps_data[counter] = Serial.read();
      counter++;
    }
    while(gps_data[counter - 1] != '\r');
    gps_data[counter] = '\0';
    if(gps_data[0] == ',')
    {
      Serial.println("No GPS data available");  
    }
    else
    {
      Serial.print("GPS data:");
      Serial.print(gps_data);  
      Serial.println("");
    }       

  }
  else
  {
    Serial.println("Error"); 
  }

  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 answer with time out
  }
  while((answer == 0) && ((millis() - previous) < timeout));    

  return answer;
}


        

Raspberry Pi:

Code:
/*
 *  Description: This example shows how to use the stand-alone GPS
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with the stand-alone GPS. For more information about the AT commands,
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2012 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.
 *
 *  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
 *  Author: Alejandro Gállego & Victor Boria
 */

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

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


int8_t answer;
int onModulePin = 2;
char gps_data[100];
int counter;


void setup()
{

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

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

  delay(3000);

  // starts GPS session in stand alone mode
  answer = sendATcommand("AT+CGPS=1,1", "OK", 1000);
  if (answer == 0)
  {
    printf("Error starting the GPS. The code stucks here!!\n");
    while (1);
  }

  printf("GPS session started\n");
}

void loop() {

  answer = sendATcommand("AT+CGPSINFO", "+CGPSINFO:", 1000);  // request info from GPS
  if (answer == 1)
  {

    counter = 0;
    do {
      while (Serial.available() == 0);
      gps_data[counter] = Serial.read();
      counter++;
    }
    while (gps_data[counter - 1] != '\r');
    gps_data[counter] = '\0';
    if (gps_data[0] == ',')
    {
      printf("No GPS data available\n");
    }
    else
    {
      printf("GPS data: %s\n", gps_data);
    }

  }
  else
  {
    printf("Error\n");
  }

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

  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();
      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;
      }
    }
    // Waits for the answer with time out
  }
  while ((answer == 0) && ((millis() - previous) < timeout));

  return answer;
}


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

        

If you want to get the NMEA sentences, you must to use the command AT+CGPSSWITCH=1 and configure the UART port at 57600 bauds. Supported NMEA sentences include GSV, GGA, RMC, GSA, and VTG.

S-GPS mode

For the S-GPS the module connects to a GPS server and the module calculates the position. Here is the example code:

Arduino:

Code:
/*
 *  Description: This example shows how to use the MS-based GPS
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with the MS-based GPS. For more information about the AT commands, 
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2013 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. 
 *  
 *  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 0.2
 *  Author: Alejandro Gallego & Victor Boria
 */
 
//Change here your data
const char pin[]="your_pin";
const char apn[]="your_apn";
const char user_name[]="your_user_name";
const char password[]="your_password";
const char gps_server[]="your_gps_server";

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


void setup(){

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

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

  delay(5000);

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

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

  // sets APN, user name and password
  snprintf(aux_str, sizeof(aux_str), "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
  sendATcommand(aux_str, "OK", 2000);

  // if not authentication requiered comment or remove the next two lines
  snprintf(aux_str, sizeof(aux_str), "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
  sendATcommand(aux_str, "OK", 2000);


  // sets GPS server
  snprintf(aux_str, sizeof(aux_str), "AT+CGPSURL=\"%s\"", gps_server);
  sendATcommand(aux_str, "OK", 2000);

  // without certificate
  sendATcommand("AT+CGPSSSL=0", "OK", 2000);

  // starts GPS session in MS-based mode
  answer = sendATcommand("AT+CGPS=1,2","OK",1000); 
  if (answer == 0)
  {
    Serial.println("Error starting the GPS");
    Serial.println("The code stucks here!!");
    while(1);
  }
}
void loop(){

  answer = sendATcommand("AT+CGPSINFO","+CGPSINFO:",1000);    // request info from GPS
  if (answer == 1)
  {

    counter = 0;
    do{
      while(Serial.available() == 0);
      gps_data[counter] = Serial.read();
      counter++;
    }
    while(gps_data[counter - 1] != '\r');
    gps_data[counter] = '\0';
    if(gps_data[0] == ',')
    {
      Serial.println("No GPS data available");  
    }
    else
    {
      Serial.print("GPS data:");
      Serial.println(gps_data);  
      Serial.println("");
    }       

  }
  else
  {
    Serial.println("Error"); 
  }

  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 answer with time out
  }
  while((answer == 0) && ((millis() - previous) < timeout));    

  return answer;
}
        

Raspberry Pi:

Code:
/*
 *  Description: This example shows how to use the MS-based GPS
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with the MS-based GPS. For more information about the AT commands,
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2012 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.
 *
 *  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
 *  Author: Alejandro Gállego & Victor Boria
 */

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

//Change here your data
const char pin[] = "your_pin";
const char apn[] = "your_apn";
const char user_name[] = "your_user_name";
const char password[] = "your_password";
const char gps_server[] = "your_gps_server";

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

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

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);
  printf("Connecting to the network...\n");

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

  printf("Succesfully connected to the network\n");

  // sets APN, user name and password
  snprintf(aux_str, sizeof(aux_str), "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
  sendATcommand(aux_str, "OK", 2000);

  // if not authentication requiered comment or remove the next two lines
  snprintf(aux_str, sizeof(aux_str), "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
  sendATcommand(aux_str, "OK", 2000);


  // sets GPS server
  snprintf(aux_str, sizeof(aux_str), "AT+CGPSURL=\"%s\"", gps_server);
  sendATcommand(aux_str, "OK", 2000);

  // without certificate
  sendATcommand("AT+CGPSSSL=0", "OK", 2000);

  // starts GPS session in MS-based mode
  answer = sendATcommand("AT+CGPS=1,2", "OK", 1000);
  if (answer == 0)
  {
    printf("Error starting the GPS. The code stucks here!!\n");
    while (1);
  }

  printf("GPS session started\n");
}


void loop() {

  answer = sendATcommand("AT+CGPSINFO", "+CGPSINFO:", 1000);  // request info from GPS
  if (answer == 1)
  {

    counter = 0;
    do {
      while (Serial.available() == 0);
      gps_data[counter] = Serial.read();
      counter++;
    }
    while (gps_data[counter - 1] != '\r');
    gps_data[counter] = '\0';
    if (gps_data[0] == ',')
    {
      printf("No GPS data available\n");
    }
    else
    {
      printf("GPS data: %s\n", gps_data);
    }

  }
  else
  {
    printf("Error\n");
  }

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

  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();
      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;
      }
    }
    // Waits for the answer with time out
  }
  while ((answer == 0) && ((millis() - previous) < timeout));

  return answer;
}


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

        

A-GPS mode

For the A-GPS the module connects to a GPS server for calculate the position. Here is the example code:

MS-assisted Server Module
Location server sends aiding data that is valid for the current fix Sending data  
Module sends code phases   Code phases
Server calculates position Calculate position  
MS-based Server Module
Location server sends aiding data that is valid for the current fix Send aiding data  
Module calculates   Calculate position
Stand alone Server Module
Module demodulates data form GPS satellite   Demodulates GPS satellite data
Module calculates position   Calculate position

GPS units

The command AT+CGPSINFO returns the GPS info in a string:

+CGPSINFO: [<latitude>],[<N/S>],[<longitude>],[<E/W>],[<date>],[<UTC_time>],[<altitude>],[<speedOG>],[<course>]

Values Format Example
latitude ddmm.mmmmmm

d: degree; m: minute
4140.831527
longitude dddmm.mmmmmm

d: degree; m: minute
00053.173495
date ddmmyy

d: day; m: month; y: year
020812
UTC_time hhmmss.s

h: hour; m: minute; s: seconds
083418.0
altitude meters 257.00
speedOG knots 2
course degrees 0

If UE-assisted mode, when fixed will report indication:

+CAGPSINFO:<latitude>,<longitude>,<altitude>,<date>,<UTC_time>

Values Format Example
latitude Unit is in 10^8 degree 4168050885
longitude Unit is in 10^8 degree 88618039
altitude meters 293
date ddmmyyyy
d: day; m: month; y: year
28092012
UTC_time hhmmss.s
h: hour; m: minute; s: seconds
081611.0

Command summary

Command Response Description
AT+CGSOCKCONT=**,&&& OK ** is the protocol and &&& Access Point Name.
AT+CGPS=*,& OK * sets on (1) or off (0) and & is the GPS mode.
AT+CGPSINFO   Gets current position information.
AT+CGPSURL=”***” OK Sets AGPS default server URL . *** is the URL.
AT+CGPSSSL=* OK Select transport security, used certificate (*=1) or not (*=0).
AT+CGPSSWITCH OK Choose the output port for NMEA sentence.

10. SMS

Sending and receiving SMS

The first code is used to send a SMS, the second one reads the SIM message memory and shows the last SMS.

Arduino:

Code:
/*
 *  Description: This example shows how to send a SMS to a desired phone.
 *  This example only shows the AT commands (and the answers of the module) used
 *  to send the SMS. For more information about the AT commands, refer to the AT 
 *  command manual.
 *
 *  Copyright (C) 2013 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. 
 *  
 *  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 0.2
 *  Author: Alejandro Gallego & Victor Boria
 */

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

//Change here your data
const char pin[]="****";
const char phone_number[]="*********";
const 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_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 );

  Serial.print("Setting SMS mode...");
  sendATcommand("AT+CMGF=1", "OK", 1000);    // sets the SMS mode to text
  Serial.println("Sending SMS");

  sprintf(aux_str,"AT+CMGS=\"%s\"", phone_number);
  answer = sendATcommand(aux_str, ">", 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 answer
    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 answer with time out
  }
  while((answer == 0) && ((millis() - previous) < timeout));    

  return answer;
}

        

Raspberry Pi:

Code:
/*
 *  Description: This example shows how to send a SMS to a desired phone.
 *  This example only shows the AT commands (and the answers of the module) used
 *  to send the SMS. For more information about the AT commands, refer to the AT
 *  command manual.
 *
 *  Copyright (C) 2012 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.
 *
 *  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
 *  Author: Alejandro Gállego & Victor Boria
 */

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


//Change here your data
const char pin[] = "****";
const char phone_number[] = "*********";   // ********* is the number to call
const char sms_text[] = "Test-Arduino-Hello World";   // ********* is the number to call

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


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

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

  printf("Succesfully connected to the network\n");

  printf("Setting SMS mode...\n");

  // sets the SMS mode to text
  sendATcommand("AT+CMGF=1", "OK", 1000);

  printf("Sending SMS\n");

  sprintf(aux_str, "AT+CMGS=\"%s\"", phone_number);
  answer = sendATcommand(aux_str, ">", 2000);    // send the SMS number
  if (answer == 1)
  {
    Serial.println(sms_text);
    printf("Message: %s\n", sms_text);
    Serial.write(0x1A);
    answer = sendATcommand("", "OK", 20000);
    if (answer == 1)
    {
      printf("Sent \n");
    }
    else
    {
      printf("Error sending\n");
    }
  }
  else
  {
    printf("Error %d\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_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();
      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;
      }
    }
    // Waits for the answer with time out
  }
  while ((answer == 0) && ((millis() - previous) < timeout));

  return answer;
}


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

        

Arduino:

Code:
/*
 *  Description: This example shows hot to read a SMS from SIM memory.
 *  This example only shows the AT commands (and the answers of the module) used
 *  to read the SMS For more information about the AT commands, refer to the AT 
 *  command manual.
 *
 *  Copyright (C) 2013 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. 
 *  
 *  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 0.2
 *  Author: Alejandro Gallego & Victor Boria 
 */
 
//Change here your data
const char pin[]="****";

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


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("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 answer
      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 answer 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 answer
    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 answer with time out
  }
  while((answer == 0) && ((millis() - previous) < timeout));    

  return answer;
}

        

Raspberry Pi:

Code:
/*
 *  Description: This example shows hot to read a SMS from SIM memory.
 *  This example only shows the AT commands (and the answers of the module) used
 *  to read the SMS For more information about the AT commands, refer to the AT
 *  command manual.
 *
 *  Copyright (C) 2012 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.
 *
 *  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
 *  Author: Alejandro Gállego & Victor Boria
 */

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


//Change here your data
const char pin[] = "****";


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


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

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("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("Message: %s\n", SMS);

  }
  else
  {
    printf("Error %d\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_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();
      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;
      }
    }
    // Waits for the answer 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+CPMS=***   Selects memory storages. *** is the memory type.
AT+CMGR=*   Reads a message. * is the number of the message.

11. E-mails

Sending an e-mail

To send e-mail a SMTP server is used, so we need an e-mail account. The code example is the next:

Arduino:

Code:
/*
 *  Description: This example shows how to get a file from a SMTP. To use SMTP
 *  and POP3 the email servers must work without SSL function.
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with SMTP. For more information about the AT commands, 
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2013 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. 
 *  
 *  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 0.2
 *  Author: Alejandro Gallego & Victor Boria
 */


//Write here you server and account data
const char smtp_server[ ] = "*********";      // SMTP server
const char smtp_user_name[ ] = "*********";   // SMTP user name
const char smtp_password[ ] = "*********";    // SMTP password
const char smtp_port[ ] = "***";              // SMTP server port

//Write here you SIM card data
const char pin_number[] = "****";
const char apn[] = "*********";
const char user_name[] = "*********";
const char password[] = "*********";

//Write here your information about sender, direcctions and names
const char sender_address[ ] = "*********";    // Sender address
const char sender_name[ ] = "*********";       // Sender name

const char to_address[ ] = "*********";        // Recipient address
const char to_name[ ] = "*********";           // Recipient name

//Write here the subject and body of the email
char subject[ ] = "Your subject";
const char body[ ] = "Hello email!";


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


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_number);
  sendATcommand(aux_str, "OK", 2000);

  delay(3000);

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

  // sets the SMTP server and port
  sprintf(aux_str, "AT+SMTPSRV=\"%s\",%s", smtp_server, smtp_port);
  sendATcommand(aux_str, "OK", 2000);

  // sets user name and password
  sprintf(aux_str, "AT+SMTPAUTH=1,\"%s\",\"%s\"", smtp_user_name, smtp_password);
  sendATcommand(aux_str, "OK", 2000);

  // sets sender adress and name
  sprintf(aux_str, "AT+SMTPFROM=\"%s\",\"%s\"", sender_address, sender_name);
  sendATcommand(aux_str, "OK", 2000);

  // sets sender adress and name
  sprintf(aux_str, "AT+SMTPRCPT=1,0,\"%s\",\"%s\"", to_address, to_name);
  sendATcommand(aux_str, "OK", 2000);

  // subjet of the email
  sprintf(aux_str, "AT+SMTPSUB=\"%s\"", subject);
  sendATcommand(aux_str, "OK", 2000);

  // body of the email
  sprintf(aux_str, "AT+SMTPBODY=\"%s\"", body);
  sendATcommand(aux_str, "OK", 2000);


  // sets APN, user name and password
  sprintf(aux_str, "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
  sendATcommand(aux_str, "OK", 2000);

  sprintf(aux_str, "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
  sendATcommand(aux_str, "OK", 2000);

  delay(2000);

  Serial.println("Sending email..."); 
  // sends the email and waits the answer of the module
  answer = sendATcommand("AT+SMTPSEND", "+SMTP: SUCCESS", 60000);
  if (answer == 1)
  {
    Serial.println("Done!");    
  }
  else
  {
    Serial.println("Error");         
  }

}

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_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 there are data in the UART input buffer, reads it and checks for the answer
    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 answer with time out
  }
  while((answer == 0) && ((millis() - previous) < timeout));    

  return answer;
}
        

Raspberry Pi:

Code:
/*
 *  Description: This example shows how to get a file from a SMTP. To use SMTP
 *  and POP3 the email servers must work without SSL function.
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with SMTP. For more information about the AT commands,
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2012 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.
 *
 *  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
 *  Author: Alejandro Gállego & Victor Boria
 */

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

//Write here you server and account data
const char smtp_server[ ] = "*********";      // SMTP server
const char smtp_user_name[ ] = "*********";   // SMTP user name
const char smtp_password[ ] = "*********";    // SMTP password
const char smtp_port[ ] = "***";              // SMTP server port

//Write here you SIM card data
const char pin_number[] = "****";
const char apn[] = "*********";
const char user_name[] = "*********";
const char password[] = "*********";

//Write here your information about sender, direcctions and names
const char sender_address[ ] = "*********";    // Sender address
const char sender_name[ ] = "*********";       // Sender name

const char to_address[ ] = "*********";        // Recipient address
const char to_name[ ] = "*********";           // Recipient name

//Write here the subject and body of the email
char subject[ ] = "Your subject";
const char body[ ] = "Hello email!";

int8_t answer, counter;
int onModulePin = 2;    // the pin to switch on the module (without press on button)
char aux_str[128];


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


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

  printf("Succesfully connected to the network\n");

  // sets the SMTP server and port
  sprintf(aux_str, "AT+SMTPSRV=\"%s\",%s", smtp_server, smtp_port);
  sendATcommand(aux_str, "OK", 2000);

  // sets user name and password
  sprintf(aux_str, "AT+SMTPAUTH=1,\"%s\",\"%s\"", smtp_user_name, smtp_password);
  sendATcommand(aux_str, "OK", 2000);

  // sets sender adress and name
  sprintf(aux_str, "AT+SMTPFROM=\"%s\",\"%s\"", sender_address, sender_name);
  sendATcommand(aux_str, "OK", 2000);

  // sets sender adress and name
  sprintf(aux_str, "AT+SMTPRCPT=1,0,\"%s\",\"%s\"", to_address, to_name);
  sendATcommand(aux_str, "OK", 2000);

  // subjet of the email
  sprintf(aux_str, "AT+SMTPSUB=\"%s\"", subject);
  sendATcommand(aux_str, "OK", 2000);

  // body of the email
  sprintf(aux_str, "AT+SMTPBODY=\"%s\"", body);
  sendATcommand(aux_str, "OK", 2000);


  // sets APN, user name and password
  sprintf(aux_str, "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
  sendATcommand(aux_str, "OK", 2000);

  sprintf(aux_str, "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
  sendATcommand(aux_str, "OK", 2000);

  delay(2000);

  printf("Sending email...\n");

  // sends the email and waits the answer of the module
  answer = sendATcommand("AT+SMTPSEND", "+SMTP: SUCCESS", 60000);
  if (answer == 1)
  {
    printf("Done!\n");
  }
  else
  {
    printf("Error\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_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();
      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;
}

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

Receiving an e-mail

For read an e-mail from a POP3 server we need an e-mail account. The code example is here:

Arduino:

Code:
/*
 *  Description: This example shows how to get a file from a POP3. To use SMTP
 *  and POP3 the email servers must work without SSL function.
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with POP3. For more information about the AT commands, 
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2013 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. 
 *  
 *  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 0.2
 *  Author: Alejandro Gallego & Victor Boria
 */

//Write here you server and account data
const char server[ ] = "*********";      
const char user_name[ ] = "*********";   
const char password[ ] = "*********";    
const char port[ ] = "***";     

//Write here you SIM card data
const char sim_pin[] = "****";
const char sim_apn[] = "*********";
const char sim_user[] = "*********";
const char sim_password[] = "*********";

char data[512];
char path[50];
int8_t answer;
int onModulePin= 2;
int counter;
unsigned long previous;
char aux_str[128];

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", sim_pin);
  sendATcommand(aux_str, "OK", 2000);

  delay(3000);

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

  // sets pop3 server
  sprintf(data, "AT+POP3SRV=\"%s\",\"%s\",\"%s\",%s", server, user_name, password, port);
  sendATcommand(data, "OK", 2000);

  // sets APN, user name and password
  sprintf(aux_str, "AT+CGSOCKCONT=1,\"IP\",\"%s\"", sim_apn);
  sendATcommand(aux_str, "OK", 2000);

  sprintf(aux_str, "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", sim_user, sim_password);
  sendATcommand(aux_str, "OK", 2000);

  delay(2000);

  // logs into the server
  answer = sendATcommand("AT+POP3IN", "OK",10000);
  if (answer == 1)
  {
    Serial.println("Logged into the server");

    // gets the first email
    answer = sendATcommand("AT+POP3GET=1", "C:/Email/",10000);
    if (answer == 1)
    {
      counter = 0;
      while(Serial.available()==0);
      do{
        path[counter] = Serial.read();
        counter++;
        if ((path[counter-1] == ' ') || (path[counter-1] == ','))
        {
          counter--;    
        }
        while(Serial.available()==0);
      }
      while (path[counter-1] != 0x0D);

      path[counter-1] = '\0';

      Serial.print("Email folder: ");                
      Serial.println(path);
    }
    else
    {
      Serial.println("Error getting the email");   
    }
    sendATcommand("AT+POP3OUT", "OK",10000);
  }

  if (answer == 1)
  {

    sendATcommand("AT+FSCD=C:/Email", "OK", 2000);
    sprintf(data, "AT+POP3READ=0,\"%s\"", path);

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

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

    counter = 0;
    previous = millis();
    answer = 0;
    data[0] = '\0';
    // this loop waits for the answer
    do{

      if(Serial.available() != 0){    
        data[counter] = Serial.read();
        counter++;
        // check if "OK" is in the response of the module
        if (strstr(data, "OK") != NULL)    
        {
          answer = 1;
        }

        // check if "ERROR" is in the response of the module
        if (strstr(data, "ERROR") != NULL)    
        {
          answer = 2;
        }
      }
      // Waits for the answer with time out
    }
    while((answer == 0) && ((millis() - previous) < 10000) && (counter < 511));   

    data[counter] = '\0';
    if (answer == 1)
    {
      Serial.println("Email:");
      Serial.println(data);        
    }
    else if (counter == 511)
    {
      Serial.println("Buffer limit reached!! Data received:");
      Serial.println(data);       
    }
    else
    {
      Serial.println("Error");
    }


  }



}
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_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 answer with time out
  }
  while((answer == 0) && ((millis() - previous) < timeout));    

  return answer;
}
        

Raspberry Pi:

Code:
/*
 *  Description: This example shows how to get a file from a POP3. To use SMTP
 *  and POP3 the email servers must work without SSL function.
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with POP3. For more information about the AT commands,
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2012 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.
 *
 *  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
 *  Author: Alejandro Gállego & Victor Boria
 */

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

//Write here you server and account data
const char server[ ] = "*********";
const char user_name[ ] = "*********";
const char password[ ] = "*********";
const char port[ ] = "***";

//Write here you SIM card data
const char sim_pin[] = "****";
const char sim_apn[] = "*********";
const char sim_user[] = "*********";
const char sim_password[] = "*********";

int answer, counter;
int onModulePin = 2;    // the pin to switch on the module (without press on button)
char aux_str[128];
char data[10000];
char path[50];
unsigned long previous;

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


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", sim_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 );

  printf("Succesfully connected to the network\n");

  // sets pop3 server
  sprintf(data, "AT+POP3SRV=\"%s\",\"%s\",\"%s\",%s", server, user_name, password, port);
  sendATcommand(data, "OK", 2000);

  // sets APN, user name and password
  sprintf(aux_str, "AT+CGSOCKCONT=1,\"IP\",\"%s\"", sim_apn);
  sendATcommand(aux_str, "OK", 2000);

  sprintf(aux_str, "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", sim_user, sim_password);
  sendATcommand(aux_str, "OK", 2000);

  delay(2000);

  // logs into the server
  answer = sendATcommand("AT+POP3IN", "OK", 10000);
  if (answer == 1)
  {
    printf("Logged into the server\n");

    // gets the first email
    answer = sendATcommand("AT+POP3GET=1", "C:/Email/", 10000);
    if (answer == 1)
    {
      counter = 0;
      while (Serial.available() == 0);
      do {
        path[counter] = Serial.read();
        counter++;
        if ((path[counter - 1] == ' ') || (path[counter - 1] == ','))
        {
          counter--;
        }
        while (Serial.available() == 0);
      } while (path[counter - 1] != 0x0D);

      path[counter - 1] = '\0';

      printf("Email folder: %s\n", path);
    }
    else
    {
      printf("Error getting the email\n");
    }
    sendATcommand("AT+POP3OUT", "OK", 10000);
  }

  //Only enter here, if it has entered in the previous "if" before
  if (answer == 1)
  {

    sendATcommand("AT+FSCD=C:/Email", "OK", 2000);
    sprintf(data, "AT+POP3READ=0,\"%s\"", path);


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

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

    counter = 0;
    previous = millis();
    answer = 0;
    data[0] = '\0';
    // this loop waits for the answer
    do {

      if (Serial.available() != 0) {
        data[counter] = Serial.read();
        counter++;
        // check if "OK" is in the response of the module
        if (strstr(data, "OK") != NULL)
        {
          answer = 1;
        }

        // check if "ERROR" is in the response of the module
        if (strstr(data, "ERROR") != NULL)
        {
          answer = 2;
        }
      }
      // Waits for the asnwer with time out
    } while ((answer == 0) && ((millis() - previous) < 10000) && (counter < 9999));

    data[counter] = '\0';
    if (answer == 1)
    {
      printf("Email: %s\n", data);
    }
    else if (counter == 511)
    {
      printf("Buffer limit reached!! Data received: %s\n", data);
    }
    else
    {
      printf("Error\n");
      printf("respuesta %s\n", data);
    }


  }

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

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

        

Command summary

Command Response Description
AT+CGSOCKCONT=**,&&& OK ** is the protocol and &&& Access Point Name.
AT+SMTPSRV=”*****”,&&& OK Sets SMTP server address and server’s port . ***** is the sever address and &&& is the server's port.
AT+SMTPAUTH=1,”***”,”&&&” OK Controls SMTP authentication. *** is the user name and &&& is the password.
AT+SMTPFROM=”***”,”&&&” OK Sets sender’s address and nam e. *** is the sender's address and &&& is the sender's name.
AT+SMTPRCPT=x,”***”,”&&&” OK Sets recipient address/name and kind . x is the kind (TO/CC/BCC), *** is the recipient address and &&& is the recipient name.
AT+SMTPSUB=”****” OK Sets the subject of e-mail . **** is the subject.
AT+SMTPBODY   Sets e-mail body.
AT+SMTPSEND   Initiates TCP session with SMTP server and sends an e-mail
AT+POP3SRV=”**”,”&&”,”xx”,yy OK Sets all parameters to get an e-mail from POP3 . ** is the server address, && is the user name, xx is the password and yy the server port
AT+POP3IN OK Logs in POP3 server
AT+POP3GET=***   Gets an e-mail from POP3 server , *** is the number of the e-mail.
AT+POP3OUT OK Logs out POP3 server
AT+POP3READ=”***”,”&&&”   Reads an e-mail from file system . *** is the location and &&& is the name.

12. SD and system memory

The file system is used to store files in a hierarchical (tree) structure. Local storage space is mapped to “C:”, and SD is mapped to “D:”. In both “C:” and “D:” directories, module creates four directories named “Picture”, “Audio”, “Video” and “VideoCall” automatically; “Picture” is used to store static image when taking picture by camera, “Audio” is used to store audio file, “Video” is used to store video file when recor ding by camera, and “VideoCall” is used to store media file which is recorded during a video call.

The maximum size of the microSD card is 32GB. Here are some AT commands to manage the file system:

AT command Response Description
AT+FSCD=**** OK Select a directory as current directory . **** is the directory.
AT+FSMKDIR=**** OK Create a new directory in current directory . **** is the name of the new directory.
AT+FSRMDIR=**** OK Delete existing directory in current directory . **** is the name of the directory to delete.
AT+FSLS   Make a list with informations of directories and/or files in current directory.
AT+DEL=**** OK Delete a file in current directory. **** is the name of the file to delete.
AT+FSRENAME=****,&&& OK Rename a file in current directory. **** is the actual name and &&& is the new name.
AT+FSATTRI=****   Request the attributes of file which is existing in current directory. **** is the name of the file.
AT+FSMEM   Check the size of available memory.
AT+FSFMT OK Format storage card which is plugged in.
AT+FSLOCA= OK Set the storage place , 0 for local and 1 for SD

13. FTP and FTPS

FTP

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

Arduino:

Code:
/*
 *  Description: This example shows how to upload a file from Arduino to a FTP 
 *  server and then download the data of the same file from the FTP server.
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with the FTP server. For more information about the AT commands, 
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2013 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. 
 *  
 *  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 0.2
 *  Author: Alejandro Gallego & Victor Boria 
 */

//Change here your data
const char pin[]="*******";
const char apn[]="*******";
const char user_name[]="*******";
const char password[]="*******";
const char ftp_server[]="*******";
const char ftp_user_name[]="*******";
const char ftp_password[]="*******";

char file_name[ ]="test.txt";
char data_to_upload[ ]="000001111122222333334444455555666667777788888999";

int8_t answer;
int onModulePin = 2, aux;
int data_size = 0;
int end_file = 0;

char aux_str[150];

char response[150];
int x = 0;
long previous;


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( (sendATcommand("AT+CREG?", "+CREG: 0,1", 500) || 
    sendATcommand("AT+CREG?", "+CREG: 0,5", 500)) == 0 );

  // sets APN, user name and password
  snprintf(aux_str, sizeof(aux_str), "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
  sendATcommand(aux_str, "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
  sendATcommand(aux_str, "OK", 2000);

  // sets the paremeters for the FTP server
  snprintf(aux_str, sizeof(aux_str), "AT+CFTPSERV=\"%s\"", ftp_server);
  sendATcommand(aux_str, "OK", 2000);

  sendATcommand("AT+CFTPPORT=21", "OK", 2000);
  sendATcommand("AT+CFTPMODE=1", "OK", 2000);
  
  snprintf(aux_str, sizeof(aux_str), "AT+CFTPUN=\"%s\"", ftp_user_name);
  sendATcommand(aux_str, "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CFTPPW=\"%s\"", ftp_password);
  sendATcommand(aux_str, "OK", 2000);

  // uploads data to the FTP server
  sprintf(aux_str, "AT+CFTPPUT=\"%s\"", file_name);
  answer = sendATcommand(aux_str, "+CFTPPUT: BEGIN", 60000);

  if (answer == 1)
  {        
    // Sends 100B to the FTP server
    Serial.println(data_to_upload);
    Serial.println(data_to_upload);

    // Sends <Ctrl+Z>
    aux_str[0] = 0x1A;
    aux_str[1] = 0x00;
    answer = sendATcommand(aux_str, "OK", 60000);

    if (answer == 1)
    {
      Serial.println("Upload done");
    }
    else
    {
      Serial.println("Upload fail");
    }
  }
  else
  {
    Serial.println("Upload fail");    
  }

  delay(10000);


  // downloads data from the FTP server
  sprintf(aux_str, "AT+CFTPGET=\"%s\"", file_name);
  answer = sendATcommand(aux_str, "+CFTPGET: DATA,", 20000);

  if (answer == 1)
  {       
    end_file = 0;

    do{
      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 != '\r');

      Serial.print("Bytes received: ");
      Serial.println(data_size, DEC);

      aux = 0;
      do{
        while(Serial.available() == 0);
        aux_str[aux] = Serial.read();
        aux++;
        data_size--;
      }
      while (data_size > 0);

      previous = millis();

      // waits 30 seconds for more data or the end of the file
      end_file = 2;
      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, "+CFTPGET: 0") != NULL)    
          {
            end_file = 1;
          }

          if (strstr(response, "+CFTPGET: DATA,") != NULL)    
          {
            end_file = 0;
          }
        }
        // Waits for the answer with time out


      }
      while((end_file == 2) && ((millis() - previous) < 30000));


    }
    while(end_file == 0);

    aux_str[aux] = '\0';

    if (end_file == 1)
    {
      Serial.println("Download done");
      Serial.print("Data received:");
      Serial.println(aux_str);
    }
    else if (end_file == 2)
    {
      Serial.println("Timeout");
    }

  }
  else
  {
    Serial.println("Download fail");    
  }


}
void loop(){



}

void power_on(){

  uint8_t answer=0;

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

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

}


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 answer with time out
  }
  while((answer == 0) && ((millis() - previous) < timeout));    

  return answer;
}
        

Raspberry Pi:

Code:
/*
 *  Description: This example shows how to upload a file from Arduino to a FTP
 *  server and then download the data of the same file from the FTP server.
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with the FTP server. For more information about the AT commands,
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2012 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.
 *
 *  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
 *  Author: Alejandro Gállego & Victor Boria
 */

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

//Change here your data
const char pin[] = "*******";
const char apn[] = "*******";
const char user_name[] = "*******";
const char password[] = "*******";
const char ftp_server[] = "*******";
const char ftp_user_name[] = "*******";
const char ftp_password[] = "*******";

char file_name[ ] = "test.txt";
char data_to_upload[ ] = "000001111122222333334444455555666667777788888999";


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

int8_t answer;
int onModulePin = 2, aux;
int data_size = 0;
int end_file = 0;

char aux_str[150];

char response[150];
int x = 0;
long previous;




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);
  printf("Connecting to the network\n");

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

  printf("Succesfully connected to the network\n");

  // sets APN, user name and password
  snprintf(aux_str, sizeof(aux_str), "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
  sendATcommand(aux_str, "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
  sendATcommand(aux_str, "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CFTPSERV=\"%s\"", ftp_server);
  sendATcommand(aux_str, "OK", 2000);

  sendATcommand("AT+CFTPPORT=21", "OK", 2000);
  sendATcommand("AT+CFTPMODE=1", "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CFTPUN=\"%s\"", ftp_user_name);
  sendATcommand(aux_str, "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CFTPPW=\"%s\"", ftp_password);
  sendATcommand(aux_str, "OK", 2000);


  printf("Starting data upload to FTP server\n");
  // uploads data to the FTP server
  sprintf(aux_str, "AT+CFTPPUT=\"%s\"", file_name);
  answer = sendATcommand(aux_str, "+CFTPPUT: BEGIN", 60000);

  if (answer == 1)
  {
    printf("Sending data\n");
    // Sends 100B to the FTP server
    Serial.println(data_to_upload);

    // Sends <Ctrl+Z>
    aux_str[0] = 0x1A;
    aux_str[1] = 0x00;
    answer = sendATcommand(aux_str, "OK", 60000);

    if (answer == 1)
    {
      printf("Upload done\n");
    }
    else
    {
      printf("Upload fail\n");
    }
  }
  else
  {
    printf("Upload fail\n");
  }

  delay(10000);

  printf("Starting data download from FTP server\n");
  // downloads data from the FTP server
  sprintf(aux_str, "AT+CFTPGET=\"%s\"", file_name);
  answer = sendATcommand(aux_str, "+CFTPGET: DATA,", 20000);

  if (answer == 1)
  {
    end_file = 0;

    do {
      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 != '\r');

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

      aux = 0;
      do {
        while (Serial.available() == 0);
        aux_str[aux] = Serial.read();
        aux++;
        data_size--;
      } while (data_size > 0);

      previous = millis();

      // waits 30 seconds for more data or the end of the file
      end_file = 2;
      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, "+CFTPGET: 0") != NULL)
          {
            end_file = 1;
          }

          if (strstr(response, "+CFTPGET: DATA,") != NULL)
          {
            end_file = 0;
          }
        }
        // Waits for the asnwer with time out


      } while ((end_file == 2) && ((millis() - previous) < 30000));


    } while (end_file == 0);

    aux_str[aux] = '\0';

    if (end_file == 1)
    {
      printf("Download done\n");
      printf("Data received: ");
      printf("%s\n", aux_str);
    }
    else if (end_file == 2)
    {
      printf("Timeout\n");
    }

  }
  else
  {
    printf("Download fail\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_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();
      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;
}

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

        

Uploading a file from local storage or SD to FTP server.

Arduino:

Code:
/*
 *  Description: This example shows how to upload a file from the 3G module 
 *  to a FTP server.
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with the FTP server. For more information about the AT commands, 
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2013 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. 
 *  
 *  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 0.2
 *  Author: Alejandro Gallego & Victor Boria
 */

//Change here your data
const char pin[]="*******";
const char apn[]="*******";
const char user_name[]="*******";
const char password[]="*******";
const char ftp_server[]="*******";
const char ftp_user_name[]="*******";
const char ftp_password[]="*******";

char file_name[ ]="test.txt";

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



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

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

  // sets APN, user name and password
  snprintf(aux_str, sizeof(aux_str), "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
  sendATcommand(aux_str, "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
  sendATcommand(aux_str, "OK", 2000);

  // sets the paremeters for the FTP server
  snprintf(aux_str, sizeof(aux_str), "AT+CFTPSERV=\"%s\"", ftp_server);
  sendATcommand(aux_str, "OK", 2000);

  sendATcommand("AT+CFTPPORT=21", "OK", 2000);
  sendATcommand("AT+CFTPMODE=1", "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CFTPUN=\"%s\"", ftp_user_name);
  sendATcommand(aux_str, "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CFTPPW=\"%s\"", ftp_password);
  sendATcommand(aux_str, "OK", 2000);

  // the file must be in the current directory (SIM5118 internal memory)
  sprintf(aux_str, "AT+CFTPPUTFILE=\"%s\",0", file_name);
  answer = sendATcommand(aux_str, "+CFTPPUTFILE: 0", 60000);

  if (answer == 1)
  {        
    Serial.println("Upload done");    
  }
  else
  {
    Serial.println("Upload fail");    
  }


}
void loop(){



}

void power_on(){

  uint8_t answer=0;

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

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

}


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


        

Raspberry Pi:

Code:
/*
 *  Description: This example shows how to upload a file from the 3G module
 *  to a FTP server.
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with the FTP server. For more information about the AT commands,
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2012 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.
 *
 *  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
 *  Author: Alejandro Gállego & Victor Boria
 */

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

//Change here your data
const char pin[] = "*******";
const char apn[] = "*******";
const char user_name[] = "*******";
const char password[] = "*******";
const char ftp_server[] = "*******";
const char ftp_user_name[] = "*******";
const char ftp_password[] = "*******";

char file_name[ ] = "test.txt";

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

int8_t answer;
int onModulePin = 2, aux;
char aux_str[1000];
char response[150];
int x = 0;
long previous;



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);
  printf("Connecting to the network\n");

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

  printf("Succesfully connected to the network\n");

  // sets APN, user name and password
  snprintf(aux_str, sizeof(aux_str), "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
  sendATcommand(aux_str, "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
  sendATcommand(aux_str, "OK", 2000);

  // sets the paremeters for the FTP server
  snprintf(aux_str, sizeof(aux_str), "AT+CFTPSERV=\"%s\"", ftp_server);
  sendATcommand(aux_str, "OK", 2000);

  sendATcommand("AT+CFTPPORT=21", "OK", 2000);
  sendATcommand("AT+CFTPMODE=1", "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CFTPUN=\"%s\"", ftp_user_name);
  sendATcommand(aux_str, "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CFTPPW=\"%s\"", ftp_password);
  sendATcommand(aux_str, "OK", 2000);

  // the file must be in "D:/Audio" directory (SD)
  sprintf(aux_str, "AT+CFTPPUTFILE=\"%s\",8", file_name);
  answer = sendATcommand(aux_str, "+CFTPPUTFILE: 8", 60000);

  if (answer == 1)
  {
    printf("Upload done\n");
  }
  else
  {
    printf("Upload fail\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_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();
      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;
}

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

        

Downloading a file from FTP server or SD to local storage.

Arduino:

Code:
/*
 *  Description: This example shows how to download from the FTP to the 3G module
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with the FTP server. For more information about the AT commands, 
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2013 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. 
 *  
 *  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 0.2
 *  Author: Alejandro Gallego & Victor Boria 
 */

//Change here your data
const char pin[]="*******";
const char apn[]="*******";
const char user_name[]="*******";
const char password[]="*******";
const char ftp_server[]="*******";
const char ftp_user_name[]="*******";
const char ftp_password[]="*******";

char file_name[ ]="test.txt";

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

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

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

  // sets APN, user name and password
  snprintf(aux_str, sizeof(aux_str), "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
  sendATcommand(aux_str, "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
  sendATcommand(aux_str, "OK", 2000);

  // sets the paremeters for the FTP server
  snprintf(aux_str, sizeof(aux_str), "AT+CFTPSERV=\"%s\"", ftp_server);
  sendATcommand(aux_str, "OK", 2000);

  sendATcommand("AT+CFTPPORT=21", "OK", 2000);
  sendATcommand("AT+CFTPMODE=1", "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CFTPUN=\"%s\"", ftp_user_name);
  sendATcommand(aux_str, "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CFTPPW=\"%s\"", ftp_password);
  sendATcommand(aux_str, "OK", 2000);

  // the file must be in the current directory
  sprintf(aux_str, "AT+CFTPGETFILE=\"%s\",0", file_name);
  answer = sendATcommand(aux_str, "+CFTPGETFILE: 0", 60000);

  if (answer == 1)
  {        
    Serial.println("Download done");    
  }
  else
  {
    Serial.println("Download fail");    
  }   

}

void loop(){ 

}

void power_on(){

  uint8_t answer=0;

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

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

}


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 answer with time out
  }
  while((answer == 0) && ((millis() - previous) < timeout));    

  return answer;
}

        

Raspberry Pi:

Code:
/*
 *  Description: This example shows how to download from the FTP to the 3G module
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with the FTP server. For more information about the AT commands,
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2012 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.
 *
 *  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
 *  Author: Alejandro Gállego & Victor Boria
 */

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

//Change here your data
const char pin[] = "*******";
const char apn[] = "*******";
const char user_name[] = "*******";
const char password[] = "*******";
const char ftp_server[] = "*******";
const char ftp_user_name[] = "*******";
const char ftp_password[] = "*******";

char file_name[ ] = "test.txt";

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

int8_t answer;
int onModulePin = 2, aux;
char aux_str[1000];
char response[150];
int x = 0;
long previous;




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);
  printf("Connecting to the network\n");

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

  printf("Succesfully connected to the network\n");

  // sets APN, user name and password
  snprintf(aux_str, sizeof(aux_str), "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
  sendATcommand(aux_str, "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
  sendATcommand(aux_str, "OK", 2000);

  // sets the paremeters for the FTP server
  snprintf(aux_str, sizeof(aux_str), "AT+CFTPSERV=\"%s\"", ftp_server);
  sendATcommand(aux_str, "OK", 2000);

  sendATcommand("AT+CFTPPORT=21", "OK", 2000);
  sendATcommand("AT+CFTPMODE=1", "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CFTPUN=\"%s\"", ftp_user_name);
  sendATcommand(aux_str, "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CFTPPW=\"%s\"", ftp_password);
  sendATcommand(aux_str, "OK", 2000);

  // the file must be in "D:/Video" directory (SD)
  sprintf(aux_str, "AT+CFTPGETFILE=\"%s\",5", file_name);
  answer = sendATcommand(aux_str, "+CFTPGETFILE: 5", 60000);

  if (answer == 1)
  {
    printf("Download done\n");
  }
  else
  {
    printf("Download fail\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_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();
      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;
}

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

        

FTPS

Creating a file into the FTP server, writing it and reading it (likes FTP codes)

Arduino:

Code:
/*
 *  Description: This example shows how to upload a file from Arduino to a FTPS 
 *  server and then download the data of the same file from the FTPS server. 
 *  The 3G module doesn’t support FTPS server with certificate authentication. 
 *  You must use an explicit FTPS server without certificate authentication.
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with the FTPS server. For more information about the AT commands, 
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2013 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. 
 *  
 *  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 0.2
 *  Author: Alejandro Gallego & Victor Boria
 */

//Change here your data
const char pin[]="*******";
const char apn[]="*******";
const char user_name[]="*******";
const char password[]="*******";
const char ftp_server[]="*******";
const char ftp_user_name[]="*******";
const char ftp_password[]="*******";
const char ftp_server_port[]="990";

char file_name[ ]="test.txt";
char data_to_upload[ ]="000001111122222333334444455555666667777788888999";

int8_t answer;
int onModulePin = 2, aux;
int data_size = 0;
int end_file = 0;

char aux_str[150];
char response[150];
int x = 0;
long previous;




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( (sendATcommand("AT+CREG?", "+CREG: 0,1", 500) || 
    sendATcommand("AT+CREG?", "+CREG: 0,5", 500)) == 0 );

  // sets APN, user name and password
  snprintf(aux_str, sizeof(aux_str), "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
  sendATcommand(aux_str, "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
  sendATcommand(aux_str, "OK", 2000);

  //It's normal if this command returns ERROR, we need to ensure it's stopped before starting it
  sendATcommand("AT+CFTPSSTOP", "OK", 5000); 


  // acquires FTPS protocol stack
  answer = sendATcommand("AT+CFTPSSTART", "OK", 5000);
  if (answer == 1)
  {     
    // login the FTPS server  
    snprintf(aux_str, sizeof(aux_str), "AT+CFTPSLOGIN=\"%s\",%s,\"%s\",\"%s\"", ftp_server, ftp_server_port, ftp_user_name, ftp_password);            
    answer = sendATcommand(aux_str, "OK", 2000);


    if (answer == 1)
    {    

      // Uploading the file
      // the file must be in the current directory
      sprintf(aux_str, "AT+CFTPSPUT=\"%s\",%d", file_name, strlen(data_to_upload));
      sendATcommand(aux_str, "OK", 2000);
      answer = sendATcommand(aux_str, "+CFTPSSPUT: 0", 60000);
      if (answer == 1)
      {
        Serial.println("Upload done");
      }
      else
      {
        Serial.println("Upload fail");        
      }


      delay(10000);

      // Downloading the file
      // downloads data from the FTP server
      sprintf(aux_str, "AT+CFTPGET=\"%s\"", file_name);
      answer = sendATcommand(aux_str, "+CFTPGET: DATA,", 20000);

      if (answer == 1)
      {       
        end_file = 0;

        do{
          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 != '\r');

          Serial.print("Bytes received: ");
          Serial.println(data_size, DEC);

          aux = 0;
          do{
            while(Serial.available() == 0);
            aux_str[aux] = Serial.read();
            aux++;
            data_size--;
          }
          while (data_size > 0);

          previous = millis();

          // waits 30 seconds for more data or the end of the file
          end_file = 2;
          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, "+CFTPGET: 0") != NULL)    
              {
                end_file = 1;
              }

              if (strstr(response, "+CFTPGET: DATA,") != NULL)    
              {
                end_file = 0;
              }
            }
            // Waits for the answer with time out


          } 
          while((end_file == 2) && ((millis() - previous) < 30000));
        }
        while(end_file == 0);

        aux_str[aux] = '\0';

        if (end_file == 1)
        {
          Serial.println("Download done");
          Serial.print("Data received:");
          Serial.println(aux_str);
        }
        else if (end_file == 2)
        {
          Serial.println("Timeout");
        }

        sendATcommand("AT+CFTPSLOGOUT", "OK", 10000);
      }
      else
      {
        Serial.println("Login fail");
      }            
      sendATcommand("AT+CFTPSSTOP", "OK", 5000);        
    }
    else
    {
      Serial.println("Error acquiring the protocol stack");    
    }

  }
  else
  {
    Serial.println("Download fail");    
  }


}
void loop(){



}

void power_on(){

  uint8_t answer=0;

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

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

}


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 answer with time out
  }
  while((answer == 0) && ((millis() - previous) < timeout));    

  return answer;
}
        

Raspberry Pi:

Code:
/*
 *  Description: This example shows how to upload a file from Arduino to a FTPS
 *  server and then download the data of the same file from the FTPS server.
 *  The 3G module doesn’t support FTPS server with certificate authentication.
 *  You must use an explicit FTPS server without certificate authentication.
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with the FTPS server. For more information about the AT commands,
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2012 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.
 *
 *  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
 *  Author: Alejandro Gállego & Victor Boria
 */

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

//Change here your data
const char pin[] = "*******";
const char apn[] = "*******";
const char user_name[] = "*******";
const char password[] = "*******";
const char ftp_server[] = "*******";
const char ftp_user_name[] = "*******";
const char ftp_password[] = "*******";
const char ftp_server_port[] = "990";

char file_name[ ] = "test.txt";
char data_to_upload[ ] = "000001111122222333334444455555666667777788888999";

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

int8_t answer;
int onModulePin = 2, aux;

char aux_str[1000];
char response[150];
int x = 0;
long previous;
int data_size = 0;
int end_file = 0;




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);
  printf("Connecting to the network\n");

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

  printf("Succesfully connected to the network\n");

  // sets APN, user name and password
  snprintf(aux_str, sizeof(aux_str), "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
  sendATcommand(aux_str, "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
  sendATcommand(aux_str, "OK", 2000);

  //It's normal if this command returns ERROR, we need to ensure it's stopped before starting it
  sendATcommand("AT+CFTPSSTOP", "OK", 5000);

  //acquires FTPS protocol stack
  answer = sendATcommand("AT+CFTPSSTART", "OK", 5000);
  if (answer == 1)
  {
    // login the FTPS server
    snprintf(aux_str, sizeof(aux_str), "AT+CFTPSLOGIN=\"%s\",%s,\"%s\",\"%s\"", ftp_server, ftp_server_port, ftp_user_name, ftp_password);
    answer = sendATcommand(aux_str, "OK", 2000);

    if (answer == 1)
    {
      // Uploading the file
      // the file must be in the current directory
      sprintf(aux_str, "AT+CFTPSPUT=\"%s\",%d", file_name, strlen(data_to_upload));
      sendATcommand(aux_str, "OK", 2000);
      answer = sendATcommand(aux_str, "+CFTPSSPUT: 0", 60000);
      if (answer == 1)
      {
        printf("Upload done\n");
      }
      else
      {
        printf("Upload fail\n");
      }


      delay(10000);

      // Downloading the file
      // downloads data from the FTP server
      sprintf(aux_str, "AT+CFTPGET=\"%s\"", file_name);
      answer = sendATcommand(aux_str, "+CFTPGET: DATA,", 20000);

      if (answer == 1)
      {
        end_file = 0;

        do {
          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 != '\r');

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

          aux = 0;
          do {
            while (Serial.available() == 0);
            aux_str[aux] = Serial.read();
            aux++;
            data_size--;
          }
          while (data_size > 0);

          previous = millis();

          // waits 30 seconds for more data or the end of the file
          end_file = 2;
          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, "+CFTPGET: 0") != NULL)
              {
                end_file = 1;
              }

              if (strstr(response, "+CFTPGET: DATA,") != NULL)
              {
                end_file = 0;
              }
            }
            // Waits for the asnwer with time out


          } while ((end_file == 2) && ((millis() - previous) < 30000));
        } while (end_file == 0);

        aux_str[aux] = '\0';

        if (end_file == 1)
        {
          printf("Download done\n");
          printf("Data received: %s\n", aux_str);
        }
        else if (end_file == 2)
        {
          printf("Timeout\n");
        }

        sendATcommand("AT+CFTPSLOGOUT", "OK", 10000);
      }
      else
      {
        printf("Login fail\n");
      }
      sendATcommand("AT+CFTPSSTOP", "OK", 5000);
    }
    else
    {
      printf("Error acquiring the protocol stack\n");
    }

  }
  else
  {
    printf("Download fail\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_answer1, unsigned int timeout)
{

  uint16_t x = 0,  answer = 0;
  char response[1000];
  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();
      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;
}

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

        

Uploading a file from local storage or SD to FTP server

Arduino:

Code:
/*
 *  Description: This example shows how to upload a file from the 3G module 
 *  to a FTPS server. The 3G module doesn’t support FTPS server with certificate
 *  authentication. You must use an explicit FTPS server without certificate 
 *  authentication.
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with the FTPS server. For more information about the AT commands, 
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2013 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. 
 *  
 *  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 0.2
 *  Author: Alejandro Gallego & Victor Boria
 */

//Change here your data
const char pin[]="*******";
const char apn[]="*******";
const char user_name[]="*******";
const char password[]="*******";
const char ftp_server[]="*******";
const char ftp_user_name[]="*******";
const char ftp_password[]="*******";
const char ftp_server_port[]="990";

char file_name[]="test.txt";

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

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

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

  // sets APN, user name and password
  snprintf(aux_str, sizeof(aux_str), "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
  sendATcommand(aux_str, "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
  sendATcommand(aux_str, "OK", 2000);

  //It's normal if this command return ERROR, we need to ensure it's stopped before starting it
  sendATcommand("AT+CFTPSSTOP", "OK", 5000); 

  // acquires FTPS protocol stack
  answer = sendATcommand("AT+CFTPSSTART", "OK", 5000);
  if (answer == 1)
  {     
    // login the FTPS server  
    snprintf(aux_str, sizeof(aux_str), "AT+CFTPSLOGIN=\"%s\",%s,\"%s\",\"%s\"", ftp_server, ftp_server_port, ftp_user_name, ftp_password);            
    answer = sendATcommand(aux_str, "OK", 2000);
    
    if (answer == 1)
    {    
      // the file must be in the current directory
      sprintf(aux_str, "AT+CFTPSPUTFILE=\"%s\",0", file_name);
      answer = sendATcommand(aux_str, "+CFTPSPUTFILE: 0", 60000);
      if (answer == 1)
      {
        Serial.println("Upload done");
      }
      else
      {
        Serial.println("Upload fail");        
      }

      sendATcommand("AT+CFTPSLOGOUT", "OK", 10000);
    }
    else
    {
      Serial.println("Login fail");
    }            
    sendATcommand("AT+CFTPSSTOP", "OK", 5000);        
  }
  else
  {
    Serial.println("Error acquiring the protocol stack");    
  }


}
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_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 answer with time out
  }
  while((answer == 0) && ((millis() - previous) < timeout));    

  return answer;
}

        

Raspberry Pi:

Code:
/*
 *  Description: This example shows how to upload a file from the 3G module
 *  to a FTPS server. The 3G module doesn’t support FTPS server with certificate
 *  authentication. You must use an explicit FTPS server without certificate
 *  authentication.
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with the FTPS server. For more information about the AT commands,
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2012 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.
 *
 *  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
 *  Author: Alejandro Gállego & Victor Boria
 */

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

//Change here your data
const char pin[] = "*******";
const char apn[] = "*******";
const char user_name[] = "*******";
const char password[] = "*******";
const char ftp_server[] = "*******";
const char ftp_user_name[] = "*******";
const char ftp_password[] = "*******";
const char ftp_server_port[] = "990";

char file_name[] = "test.txt";

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

int8_t answer;
int onModulePin = 2, aux;


char aux_str[1000];
char response[150];
int x = 0;
long previous;


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);
  printf("Connecting to the network\n");

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

  printf("Succesfully connected to the network\n");

  // sets APN, user name and password
  snprintf(aux_str, sizeof(aux_str), "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
  sendATcommand(aux_str, "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
  sendATcommand(aux_str, "OK", 2000);

  //It's normal if this command return ERROR, we need to ensure it's stopped before starting it
  sendATcommand("AT+CFTPSSTOP", "OK", 5000);

  // acquires FTPS protocol stack
  answer = sendATcommand("AT+CFTPSSTART", "OK", 5000);
  if (answer == 1)
  {
    // login the FTPS server
    snprintf(aux_str, sizeof(aux_str), "AT+CFTPSLOGIN=\"%s\",%s,\"%s\",\"%s\"", ftp_server, ftp_server_port, ftp_user_name, ftp_password);
    answer = sendATcommand(aux_str, "OK", 2000);

    if (answer == 1)
    {
      // the file must be in the current directory
      sprintf(aux_str, "AT+CFTPSPUTFILE=\"%s\",0", file_name);
      answer = sendATcommand(aux_str, "+CFTPSPUTFILE: 0", 60000);
      if (answer == 1)
      {
        printf("Upload done\n");
      }
      else
      {
        printf("Upload fail\n");
      }

      sendATcommand("AT+CFTPSLOGOUT", "OK", 10000);
    }
    else
    {
      printf("Login fail\n");
    }
    sendATcommand("AT+CFTPSSTOP", "OK", 5000);
  }
  else
  {
    printf("Error acquiring the protocol stack\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_answer1, unsigned int timeout)
{

  uint16_t x = 0,  answer = 0;
  char response[1000];
  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();
      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;
}

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

        

Downloading a file from FTPS server or SD to local storage

Arduino:

Code:
/*
 *  Description: This example shows how to download from the FTPS to the 3G module
 *  The 3G module doesn’t support FTPS server with certificate authentication. 
 *  You must use an explicit FTPS server without certificate authentication.
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with the FTPS server. For more information about the AT commands, 
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2013 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. 
 *  
 *  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 0.2
 *  Author: Alejandro Gallego & Victor Boria
 */

//Change here your data
const char pin[]="*******";
const char apn[]="*******";
const char user_name[]="*******";
const char password[]="*******";
const char ftp_server[]="*******";
const char ftp_user_name[]="*******";
const char ftp_password[]="*******";
const char ftp_server_port[]="990";

char file_name[]="test.txt";

int8_t answer;
int onModulePin= 2;

char aux_str[50];

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

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

  // sets APN, user name and password
  snprintf(aux_str, sizeof(aux_str), "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
  sendATcommand(aux_str, "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
  sendATcommand(aux_str, "OK", 2000);

  //It's normal if this command return ERROR, we need to ensure it's stopped before starting it
  sendATcommand("AT+CFTPSSTOP", "OK", 5000); 

  // acquires FTPS protocol stack
  answer = sendATcommand("AT+CFTPSSTART", "OK", 5000);
  if (answer == 1)
  {     
    // login the FTPS server  
    snprintf(aux_str, sizeof(aux_str), "AT+CFTPSLOGIN=\"%s\",%s,\"%s\",\"%s\"", ftp_server, ftp_server_port, ftp_user_name, ftp_password);            
    answer = sendATcommand(aux_str, "OK", 2000);

    if (answer == 1)
    {    
      // the file must be in the current directory
      sprintf(aux_str, "AT+CFTPSGETFILE=\"%s\",0", file_name);
      answer = sendATcommand(aux_str, "+CFTPSGETFILE: 0", 60000);
      if (answer == 1)
      {
        Serial.println("Download done");
      }
      else
      {
        Serial.println("Download fail");        
      }

      sendATcommand("AT+CFTPSLOGOUT", "OK", 10000);
    }
    else
    {
      Serial.println("Login fail");
    }            
    sendATcommand("AT+CFTPSSTOP", "OK", 5000);        
  }
  else
  {
    Serial.println("Error acquiring the protocol stack");    
  }


}
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_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 answer with time out
  }
  while((answer == 0) && ((millis() - previous) < timeout));    

  return answer;
}
        

Raspberry Pi:

Code:
/*
 *  Description: This example shows how to download from the FTPS to the 3G module
 *  The 3G module doesn’t support FTPS server with certificate authentication.
 *  You must use an explicit FTPS server without certificate authentication.
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with the FTPS server. For more information about the AT commands,
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2012 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.
 *
 *  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
 *  Author: Alejandro Gállego & Victor Boria
 */

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

//Change here your data
const char pin[] = "*******";
const char apn[] = "*******";
const char user_name[] = "*******";
const char password[] = "*******";
const char ftp_server[] = "*******";
const char ftp_user_name[] = "*******";
const char ftp_password[] = "*******";
const char ftp_server_port[] = "990";

char file_name[] = "test.txt";

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

int8_t answer;
int onModulePin = 2, aux;


char aux_str[1000];
char response[150];
int x = 0;
long previous;


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);
  printf("Connecting to the network\n");

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

  printf("Succesfully connected to the network\n");

  // sets APN, user name and password
  snprintf(aux_str, sizeof(aux_str), "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
  sendATcommand(aux_str, "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
  sendATcommand(aux_str, "OK", 2000);

  //It's normal if this command return ERROR, we need to ensure it's stopped before starting it
  sendATcommand("AT+CFTPSSTOP", "OK", 5000);

  // acquires FTPS protocol stack
  answer = sendATcommand("AT+CFTPSSTART", "OK", 5000);
  if (answer == 1)
  {
    // login the FTPS server
    snprintf(aux_str, sizeof(aux_str), "AT+CFTPSLOGIN=\"%s\",%s,\"%s\",\"%s\"", ftp_server, ftp_server_port, ftp_user_name, ftp_password);
    answer = sendATcommand(aux_str, "OK", 2000);

    if (answer == 1)
    {
      // the file must be in the current directory
      sprintf(aux_str, "AT+CFTPSGETFILE=\"%s\",0", file_name);
      answer = sendATcommand(aux_str, "+CFTPSGETFILE: 0", 60000);
      if (answer == 1)
      {
        printf("Download done\n");
      }
      else
      {
        printf("Download fail\n");
      }

      sendATcommand("AT+CFTPSLOGOUT", "OK", 10000);
    }
    else
    {
      printf("Login fail\n");
    }
    sendATcommand("AT+CFTPSSTOP", "OK", 5000);
  }
  else
  {
    printf("Error acquiring the protocol stack\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_answer1, unsigned int timeout)
{

  uint16_t x = 0,  answer = 0;
  char response[1000];
  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();
      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;
}

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

        

Command summary

AT command Response Description
AT+CGSOCKCONT=**,&&& OK ** is the protocol and &&& Access Point Name.
AT+CFTPSERV=”****”   Sets FTP server domain name or IP address. **** is the domain name or the IP.
AT+CFTPPORT=*** OK Sets FTP server port. *** is the port.
AT+CFTPUN=”***” OK Sets user name for FTP server access. *** is the user name.
AT+CFTPPW=”***” OK Sets password for FTP server access. *** is the password.
AT+CFTPMODE= OK Sets FTP mode. 1 for passive or 0 for proactive.
AT+CFTPTYPE= OK Sets the transfer type on FTP server . A for ASCII or I for binary.
AT+CFTPPUT=”***”,&&   Puts a file from FTP server to serial port . *** is the path with the name of the file and && is the length.
AT+CFTPGET=”***”   Gets a file from FTP server to serial port . *** is the path with the name of the file.
AT+CFTPPUTFILE=”***”,&   Uploads a file to FTP server from module . *** is the path and & is the storage directory.
AT+CFTPGETFILE”=***”,&   Downloads a file from FTP server to module . *** is the path with the name and & is the storage directory.
AT+CFTPSSTART OK Acquires FTPS protocol stack.
AT+CFTPSLOGIN=”**”,&&&,”xxx”,”yyy” OK Logs in FTPS server. *** is the host address, &&& is the port, xxx is the user name and yyy is the password.
AT+CFTPSTYPE= OK Sets the transfer type on FTPS server . A for ASCII or I for binary.
AT+CFTPSPUT=”***”,&&   Puts a file from FTPS server to serial port . *** is the path with the name of the file and && is the length.
AT+CFTPSGET=”***”   Gets a file from FTPS server to serial port . *** is the path with the name of the file.
AT+CFTPSPUTFILE=”***”,&   Uploads a file to FTPS server from module . *** is the path and & is the storage directory.
AT+CFTPSGETFILE=”***”,&   Downloads a file from FTPS server to module . *** is the path with the name and & is the storage directory.

14. TCP and UDP

UDP client

Sending data to a UDP server:

Arduino:

Code:
/*
 *  Description: This example shows how to use UDP clients in singleclient mode
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with the UDP. For more information about the AT commands, 
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2013 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. 
 *  
 *  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 0.2
 *  Author: Alejandro Gallego & Victor Boria
 */

//Change here your data
const char pin[]="*******";
const char apn[]="*******";
const char user_name[]="*******";
const char password[]="*******";
const char UDP_server[]="*******";
const char UDP_port[]="*******";
char UDP_message[]="*******";

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

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( (sendATcommand("AT+CREG?", "+CREG: 0,1", 500) || 
    sendATcommand("AT+CREG?", "+CREG: 0,5", 500)) == 0 );

  // sets APN, user name and password
  snprintf(aux_str, sizeof(aux_str), "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
  sendATcommand(aux_str, "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
  sendATcommand(aux_str, "OK", 2000);
}

void loop(){

  sprintf(aux_str, "AT+NETOPEN=\"UDP\",%s", UDP_port);
  answer = sendATcommand(aux_str, "Network opened", 20000);

  if (answer == 1)
  {
    Serial.println("Network opened");
    sprintf(aux_str, "AT+UDPSEND=%d,\"%s\",%s", strlen(UDP_message), UDP_server, UDP_port);
    answer = sendATcommand(aux_str, ">", 20000);
    if (answer == 1)
    {
      sendATcommand(UDP_message, "OK", 20000);
    }
    sendATcommand("AT+NETCLOSE", "OK", 20000);
  }
  else
  {
    Serial.println("Error opening the network");    
  }

}

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 answer with time out
  }
  while((answer == 0) && ((millis() - previous) < timeout));    

  return answer;
}
        

Raspberry Pi:

Code:
/*
 *  Description: This example shows how to use UDP clients in singleclient mode
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with the UDP. For more information about the AT commands,
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2012 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.
 *
 *  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
 *  Author: Alejandro Gállego & Victor Boria
 */

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

//Change here your data
const char pin[] = "*******";
const char apn[] = "*******";
const char user_name[] = "*******";
const char password[] = "*******";
const char UDP_server[] = "*******";
const char UDP_port[] = "*******";
const char UDP_message[] = "*******";

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

int8_t answer;
int onModulePin = 2, aux;


char aux_str[1000];
char response[150];
int x = 0;
long previous;



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);
  printf("Connecting to the network\n");

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

  printf("Succesfully connected to the network\n");

  // sets APN, user name and password
  snprintf(aux_str, sizeof(aux_str), "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
  sendATcommand(aux_str, "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
  sendATcommand(aux_str, "OK", 2000);
}

void loop() {

  sprintf(aux_str, "AT+NETOPEN=\"UDP\",%s", UDP_port);
  answer = sendATcommand(aux_str, "Network opened", 20000);

  if (answer == 1)
  {
    printf("Network opened\n");

    sprintf(aux_str, "AT+UDPSEND=%d,\"%s\",%s", strlen(UDP_message), UDP_server, UDP_port);
    answer = sendATcommand(aux_str, ">", 20000);
    if (answer == 1)
    {
      sendATcommand(UDP_message, "OK", 20000);
    }
    sendATcommand("AT+NETCLOSE", "OK", 20000);
  }
  else
  {
    printf("Error opening the network\n");
  }
}


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)
{

  uint16_t x = 0,  answer = 0;
  char response[1000];
  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();
      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;
}

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

        

TCP client

Sending data to a TCP server:

Arduino:

Code:
/*
 *  Description: This example shows how to use TCP clients in single client mode
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with the TCP/IP. For more information about the AT commands, 
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2013 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. 
 *  
 *  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 0.2
 *  Author: Alejandro Gallego & Victor Boria
 */

//Change here your data
const char pin[]="*******";
const char apn[]="*******";
const char user_name[]="*******";
const char password[]="*******";
const char TCP_server_1[ ]="*******";
const char TCP_port_1[ ]="*******";
char TCP_message_1[ ]="*******";

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


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( (sendATcommand("AT+CREG?", "+CREG: 0,1", 500) || 
    sendATcommand("AT+CREG?", "+CREG: 0,5", 500)) == 0 );

  // sets APN, user name and password
  snprintf(aux_str, sizeof(aux_str), "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
  sendATcommand(aux_str, "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
  sendATcommand(aux_str, "OK", 2000);
}

void loop(){

  sprintf(aux_str, "AT+NETOPEN=\"TCP\",%s", TCP_port_1);
  answer = sendATcommand(aux_str, "Network opened", 20000);

  if (answer == 1)
  {
    Serial.println("Network opened");
    sprintf(aux_str, "AT+TCPCONNECT=\"%s\",%s", TCP_server_1, TCP_port_1);
    answer = sendATcommand(aux_str, "Connect ok", 20000);
    if (answer == 1)
    {
      Serial.println("Socket opened");
      sprintf(aux_str, "AT+TCPWRITE=%d", strlen(TCP_message_1));
      answer = sendATcommand(aux_str, ">", 20000);
      if (answer == 1)
      {
        sendATcommand(TCP_message_1, "Send OK", 20000);                
      }
      sendATcommand("AT+NETCLOSE", "OK", 20000);
    }
    else
    {
      Serial.println("Error opening the socket");    
    }
  }
  else
  {
    Serial.println("Error opening the network");    
  }

}

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

Raspberry Pi:

Code:
/*
 *  Description: This example shows how to use TCP clients in single client mode
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with the TCP/IP. For more information about the AT commands, 
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2012 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.
 *
 *  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
 *  Author: Alejandro Gállego & Victor Boria
 */

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

//Change here your data
const char pin[]="*******";
const char apn[]="*******";
const char user_name[]="*******";
const char password[]="*******";
const char TCP_server_1[ ]="*******";
const char TCP_port_1[ ]="*******";
const char TCP_message_1[ ]="*******";

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

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


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);
    printf("Connecting to the network\n");

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

    printf("Succesfully connected to the network\n");

    // sets APN, user name and password
    snprintf(aux_str, sizeof(aux_str), "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
    sendATcommand(aux_str, "OK", 2000);

    snprintf(aux_str, sizeof(aux_str), "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
    sendATcommand(aux_str, "OK", 2000);
}

void loop(){
  sprintf(aux_str, "AT+NETOPEN=\"TCP\",%s", TCP_port_1);
  answer = sendATcommand(aux_str, "Network opened", 20000);

  if (answer == 1)
  {
        printf("Network opened\n");
     
		sprintf(aux_str, "AT+TCPCONNECT=\"%s\",%s", TCP_server_1, TCP_port_1);
		answer = sendATcommand(aux_str, "Connect ok", 20000);
    if (answer == 1)
    {
      printf("Socket opened\n");
      sprintf(aux_str, "AT+TCPWRITE=%d", strlen(TCP_message_1));
      answer = sendATcommand(aux_str, ">", 20000);
      if (answer == 1)
      {
        sendATcommand(TCP_message_1, "Send OK", 20000);                
      }
      sendATcommand("AT+NETCLOSE", "OK", 20000);
    }
    else
    {
      printf("Error opening the socket\n");    
    }
  }
  else
  {
    printf("Error opening the network\n");    
  }

}


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)
{

    uint16_t x=0,  answer=0;
    char response[1000];
    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();
            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;
}

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

Multiclient

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

Arduino:

Code:
/*
 *  Description: This example shows how to use TCP clients in multiclient mode
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with the TCP/IP. For more information about the AT commands, 
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2013 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. 
 *  
 *  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 0.2
 *  Author: Alejandro Gallego & Victor Boria
 */

//Change here your data
const char pin[]="*******";
const char apn[]="*******";
const char user_name[]="*******";
const char password[]="*******";
const char TCP_server_1[ ]="*******";
const char TCP_port_1[ ]="*******";
char TCP_message_1[ ]="*******";
const char TCP_server_2[ ]="*******";
const char TCP_port_2[ ]="*******";
char TCP_message_2[ ]="*******";

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

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( (sendATcommand("AT+CREG?", "+CREG: 0,1", 500) ||
    sendATcommand("AT+CREG?", "+CREG: 0,5", 500)) == 0 );

  // sets APN, user name and password
  snprintf(aux_str, sizeof(aux_str), "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
  sendATcommand(aux_str, "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
  sendATcommand(aux_str, "OK", 2000);
}

void loop(){
  sprintf(aux_str, "AT+NETOPEN=,,1");
  answer = sendATcommand(aux_str, "Network opened", 20000);

  if (answer == 1)
  {
    Serial.println("Network opened");
    Serial.println("Opening client 1");

    sprintf(aux_str, "AT+CIPOPEN=0,\"TCP\",\"%s\",%s", TCP_server_1, TCP_port_1);
    answer = sendATcommand(aux_str, "OK", 20000);
    if (answer == 1)
    {
      Serial.println("Client 1 opened");
      sprintf(aux_str, "AT+CIPSEND=0,%d", strlen(TCP_message_1));        
      answer = sendATcommand(aux_str, ">", 20000);
      if (answer == 1)
      {
        sendATcommand(TCP_message_1, "OK", 20000);                
      }         
    }
    sendATcommand("AT+CIPCLOSE=0", "OK", 20000);


    Serial.println("Opening client 2");

    sprintf(aux_str, "AT+CIPOPEN=1,\"TCP\",\"%s\",%s", TCP_server_2, TCP_port_2);
    answer = sendATcommand(aux_str, "OK", 20000);
    if (answer == 1)
    {
      Serial.println("Client 2 opened");
      sprintf(aux_str, "AT+CIPSEND=1,%d", strlen(TCP_message_2));
      answer = sendATcommand(aux_str, ">", 20000);
      if (answer == 1)
      {
        sendATcommand(TCP_message_2, "OK", 20000);                
      }         
    }
    sendATcommand("AT+CIPCLOSE=1", "OK", 20000);
  }
  else
  {
    Serial.println("Error opening the network");    
  }

}

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

Raspberry Pi:

Code:
/*
 *  Description: This example shows how to use TCP clients in multiclient mode
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with the TCP/IP. For more information about the AT commands,
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2012 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.
 *
 *  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
 *  Author: Alejandro Gállego & Victor Boria
 */

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

//Change here your data
const char pin[] = "*******";
const char apn[] = "*******";
const char user_name[] = "*******";
const char password[] = "*******";
const char TCP_server_1[ ] = "*******";
const char TCP_port_1[ ] = "*******";
char TCP_message_1[ ] = "*******";
const char TCP_server_2[ ] = "*******";
const char TCP_port_2[ ] = "*******";
char TCP_message_2[ ] = "*******";

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

int8_t answer;
int onModulePin = 2, aux;

char aux_str[1000];



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);
  printf("Connecting to the network\n");

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

  printf("Succesfully connected to the network\n");

  // sets APN, user name and password
  snprintf(aux_str, sizeof(aux_str), "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
  sendATcommand(aux_str, "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
  sendATcommand(aux_str, "OK", 2000);
}

void loop() {
  sprintf(aux_str, "AT+NETOPEN=,,1");
  answer = sendATcommand(aux_str, "Network opened", 20000);

  if (answer == 1)
  {
    printf("Network opened\n");
    printf("Opening client 1\n");

    sprintf(aux_str, "AT+CIPOPEN=0,\"TCP\",\"%s\",%s", TCP_server_1, TCP_port_1);
    answer = sendATcommand(aux_str, "OK", 20000);
    if (answer == 1)
    {
      printf("Client 1 opened\n");
      sprintf(aux_str, "AT+CIPSEND=0,%d", strlen(TCP_message_1));
      answer = sendATcommand(aux_str, ">", 20000);
      if (answer == 1)
      {
        sendATcommand(TCP_message_1, "OK", 20000);
      }
    }
    sendATcommand("AT+CIPCLOSE=0", "OK", 20000);

    printf("Opening client 2\n");

    sprintf(aux_str, "AT+CIPOPEN=1,\"TCP\",\"%s\",%s",
            TCP_server_2, TCP_port_2);
    answer = sendATcommand(aux_str, "OK", 20000);
    if (answer == 1)
    {
      printf("Client 2 opened\n");
      sprintf(aux_str, "AT+CIPSEND=1,%d", strlen(TCP_message_2));
      answer = sendATcommand(aux_str, ">", 20000);
      if (answer == 1)
      {
        sendATcommand(TCP_message_2, "OK", 20000);
      }
    }
    sendATcommand("AT+CIPCLOSE=1", "OK", 20000);
  }
  else
  {
    printf("Error opening the network\n");
  }

}


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)
{

  uint16_t x = 0,  answer = 0;
  char response[1000];
  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();
      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;
}

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

        

TCP server

SIM5218 allows to create a TCP server with a maximum of ten TCP clients. In this example the server send a message every 5 seconds to all clients.

Arduino:

Code:
/*
 *  Description: This example shows how to use TCP server.
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with the TCP/IP. For more information about the AT commands, 
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2013 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. 
 *  
 *  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 0.2
 *  Author: Alejandro Gallego & Victor Boria
 */

//Change here your data
const char pin[]="*******";
const char apn[]="*******";
const char user_name[]="*******";
const char password[]="*******";
const char port[ ]="*****";
char server_message[ ]="*****";

char server_IP[16];
int8_t client;
int8_t answer;
int onModulePin= 2;
int x;
unsigned long previous;
char aux_str[250];


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( (sendATcommand("AT+CREG?", "+CREG: 0,1", 500) || 
    sendATcommand("AT+CREG?", "+CREG: 0,5", 500)) == 0 );

  // sets APN, user name and password
  snprintf(aux_str, sizeof(aux_str), "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
  sendATcommand(aux_str, "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
  sendATcommand(aux_str, "OK", 2000);
}

void loop(){
  sprintf(aux_str, "AT+NETOPEN=\"TCP\",%s", port);
  answer = sendATcommand(aux_str, "Network opened", 20000);

  if (answer == 1)
  {
    Serial.println("Network opened");
    answer = sendATcommand("AT+SERVERSTART", "OK", 20000);
    if (answer == 1)
    {
      Serial.println("Server started");

      sendATcommand("AT+IPADDR", "+IPADDR: ", 20000);

      x = 0;
      do{ 
        while( Serial.available() == 0);
        server_IP[x] = Serial.read();
        x++;
      }
      while(server_IP[x-1] != 0x0D);
      server_IP[x-1] != '\0';


      Serial.print("Server IP: ");
      Serial.println(server_IP);

      do{

        Serial.println("Waiting for clients...");

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

        Serial.println("AT+LISTCLIENT");         

        x = 0;
        previous = millis();

        client = 0;
        answer = 0;
        // this loop waits for the answer
        do{

          if(Serial.available() != 0){    
            aux_str[x] = Serial.read();
            if (aux_str[x] == 0x0D)
            {
              client++;    
            }
            x++;
            if (strstr(aux_str, "OK") != NULL)    
            {
              answer = 1;
            }
            if (strstr(aux_str, "ERROR") != NULL)    
            {
              answer = 2;
            }
          }
          // Waits for the asnwer with time out
        }
        while((answer == 0) && ((millis() - previous) < 10000));

        Serial.println(client, DEC);
        Serial.println(aux_str);  
        client -= 2;

        if (client > 0 && (answer == 1))
        {
          Serial.print("Clients connected: "); 
          Serial.println(client, DEC); 

          for(int y = 0; y < client; y++)
          {
            sprintf(aux_str, "AT+ACTCLIENT=%d", client);
            if (sendATcommand(aux_str, "OK", 10000) == 1)
            { 
              sprintf(aux_str, "AT+TCPWRITE=%d", strlen(server_message));
              answer = sendATcommand(aux_str, ">", 20000);
              if (answer == 1)
              {
                sendATcommand(server_message, "Send OK", 20000);                
              }
              sprintf(aux_str, "AT+CLOSECLIENT=%d", client);
              sendATcommand(aux_str, "OK", 20000);
            }
          }
        }
        else
        {
          Serial.println("No clients connected");
        } 
        delay(5000);
      }
      while (client <= 0);

      sendATcommand("AT+NETCLOSE", "OK", 20000);
    }
    else
    {
      Serial.println("Error opening the socket");    
    }
  }
  else
  {
    Serial.println("Error opening the network");    
  }

}

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

Raspberry Pi:

Code:
/*
 *  Description: This example shows how to use TCP server.
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with the TCP/IP. For more information about the AT commands,
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2012 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.
 *
 *  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
 *  Author: Alejandro Gállego & Victor Boria
 */

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

//Change here your data
const char pin[] = "*******";
const char apn[] = "*******";
const char user_name[] = "*******";
const char password[] = "*******";
const char port[ ] = "*****";
char server_message[ ] = "*****";

char server_IP[16];

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

int8_t client;
int8_t answer;
int onModulePin = 2, aux;
int x;
unsigned long previous;
char aux_str[1000];



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);
  printf("Connecting to the network\n");

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

  printf("Succesfully connected to the network\n");

  // sets APN, user name and password
  snprintf(aux_str, sizeof(aux_str), "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
  sendATcommand(aux_str, "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
  sendATcommand(aux_str, "OK", 2000);
}

void loop() {

  sprintf(aux_str, "AT+NETOPEN=\"TCP\",%s", port);
  answer = sendATcommand(aux_str, "Network opened", 20000);

  if (answer == 1)
  {
    printf("Network opened\n");
    answer = sendATcommand("AT+SERVERSTART", "OK", 20000);
    if (answer == 1)
    {
      printf("Server started\n");

      sendATcommand("AT+IPADDR", "+IPADDR: ", 20000);

      x = 0;
      do {
        while ( Serial.available() == 0);
        server_IP[x] = Serial.read();
        x++;
      } while (server_IP[x - 1] != 0x0D);
      server_IP[x - 1] != '\0';

      printf("Server IP: %s\n", server_IP);

      do {
        printf("Waiting for clients...\n");

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

        Serial.println("AT+LISTCLIENT");

        x = 0;
        previous = millis();

        client = 0;
        answer = 0;
        // this loop waits for the answer
        do {

          if (Serial.available() != 0) {
            aux_str[x] = Serial.read();
            if (aux_str[x] == 0x0D)
            {
              client++;
            }
            x++;
            if (strstr(aux_str, "OK") != NULL)
            {
              answer = 1;
            }
            if (strstr(aux_str, "ERROR") != NULL)
            {
              answer = 2;
            }
          }
          // Waits for the asnwer with time out
        } while ((answer == 0) && ((millis() - previous) < 10000));

        Serial.println(client, DEC);
        Serial.println(aux_str);
        client -= 2;

        if (client > 0 && (answer == 1))
        {
          printf("Clients connected: %d\n", client);

          for (int y = 0; y < client; y++)
          {
            sprintf(aux_str, "AT+ACTCLIENT=%d", client);
            if (sendATcommand(aux_str, "OK", 10000) == 1)
            {
              sprintf(aux_str, "AT+TCPWRITE=%d", strlen(server_message));
              answer = sendATcommand(aux_str, ">", 20000);
              if (answer == 1)
              {
                sendATcommand(server_message, "Send OK", 20000);
              }
              sprintf(aux_str, "AT+CLOSECLIENT=%d", client);
              sendATcommand(aux_str, "OK", 20000);
            }
          }
        }
        else
        {
          printf("No clients connected\n");
        }
        delay(5000);
      }
      while (client <= 0);

      sendATcommand("AT+NETCLOSE", "OK", 20000);
    }
    else
    {
      printf("Error opening the socket\n");
    }
  }
  else
  {
    printf("Error opening the network\n");
  }
}


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)
{

  uint16_t x = 0,  answer = 0;
  char response[1000];
  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();
      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;
}

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

        

Command summary

AT command Response Description
AT+NETOPEN=”***”,&&   Opens a socket . *** is the socket type and && is the port.
AT+NETCLOSE OK Closes socket.
AT+UPDSEND   Sends UDP data.
     
AT+TCPCONNECT=”***”,&&   Establishes TCP connection with TCP server. *** is the IP address and && is the port.
AT+TCPWRITE   Sends TCP data when the TCP connection is established.
AT+SERVERSTART OK Starts up TCP server.
AT+LISTCLIENT   Lists all of clients’ information.
AT+ACTCLIENT=* OK Activates the specified client. * is the number of the client.
AT+CLOSECLIENT=* OK Disconnects the specified client. * is the number of the client.
     
AT+CIPOPEN=*,”&&”,”xx”,yy   Establish a connection with TCP server or UDP server. * is the number of the connection, && is the type of transmision protocol, xx is the server IP and yy is the server port.
AT+CIPSEND   Sends some data to remote host in mult-client mode.
AT+CIPCLOSE=* OK Closes a specified connection in multi-client mode. * is the number of the connection.

15. HTTP AND HTTPS

HTTP

SIM5218 can launch a HTTP operation like GET or POST. Here is an example with GET operation. As you can read in the header of the code, you will need to increase the buffer size to 400 bytes.

Arduino:

Code:
/*
 *  Description: This example shows the AT commands (and the answers of the module) 
 *  used to work with HTTP to do a GET method to our server in Libelium.
 *  For more information about the AT commands, refer to the AT command manual.
 * 
 *  IMPORTANT: You need to increase the length of the buffer to 400 changing these  
 *  lines in the file HardwareSerial.h (/arduino-1.0.X/hardware/arduino/cores/arduino):
 *  #if (RAMEND < 1000) 
 *	#define SERIAL_BUFFER_SIZE 400 
 *	#else 
 *	#define SERIAL_BUFFER_SIZE 400 
 *	#endif
 *
 *  Copyright (C) 2012 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.
 *
 *  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
 *  Author: Alejandro Gállego & Victor Boria
 */

//Change here your data
const char pin_number[] = "****";
const char apn[] = "*********";
const char user_name[] = "*********";
const char password[] = "*********";

char url[ ]="test.libelium.com";
int port= 80;
char request[ ]="GET /test-get-post.php?a=1&b=2 HTTP/1.1\r\nHost: test.libelium.com\r\nContent-Length: 0\r\n\r\n";


int8_t answer;
int onModulePin = 2, aux;
int data_size = 0;
int end_file = 0;
char aux_str[50];
char data[400];
int http_x;
int http_status; // 0: end, 1 waiting data with header, 2 waiting data without header, 3 timeout waiting data, 4 unknow response
int x = 0;
long previous;

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_number);
  sendATcommand(aux_str, "OK", 2000);

  delay(3000);

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

  // sets APN, user name and password
  sprintf(aux_str, "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
  sendATcommand(aux_str, "OK", 2000);

  sprintf(aux_str, "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
  sendATcommand(aux_str, "OK", 2000);
}

void loop(){

  // request the url
  
  previous = millis();
  sprintf(aux_str, "AT+CHTTPACT=\"%s\",%d", url, port);
  answer = sendATcommand(aux_str, "+CHTTPACT: REQUEST", 60000);

  // Sends the request
  Serial.println(request);
  // Sends <Ctrl+Z>
  Serial.write(0x1A);
  http_status = 1;

  while ((http_status == 1) || (http_status == 2))
  {
    answer = sendATcommand("", "+CHTTPACT: ", 60000);
    if (answer == 0)
    {
      if (http_status == 1)
      {
        http_status = 3;
      }
      if (http_status == 2)
      {
        http_status = 5;
      }
    }
    else
    {
      // answer == 1
      while(Serial.available()==0);
      aux_str[0] = Serial.read();
      
      if ((aux_str[0] == 'D') && (http_status == 1))
      {
        // Data packet with header
        while(Serial.available()<4);
        Serial.read();  // A
        Serial.read();  // T
        Serial.read();  // A
        Serial.read();  // ,

        // Reads the packet size
        x=0;
        do{
          while(Serial.available()==0);
          aux_str[x] = Serial.read();
          x++;
        }
        while((aux_str[x-1] != '\r') && (aux_str[x-1] != '\n'));

        aux_str[x-1] = '\0';
        data_size = atoi(aux_str);

        // Now, search the end of the HTTP header (\r\n\r\n)
        do{
          while (Serial.available() < 3);

          data_size--;
          if (Serial.read() == '\r')
          {
            data_size--;
            if (Serial.read() == '\n')
            {
              data_size--;
              if (Serial.read() == '\r')
              {
                data_size--;
                if (Serial.read() == '\n')
                {
                  // End of the header found
                  http_status = 2;
                }
              }
            }	
          }
        }
        while ((http_status == 1) && (data_size > 0));

        if (http_status == 2)
        {
          // Reads the data
          http_x = 0;
          do{
            if(Serial.available() != 0){
              data[http_x] = Serial.read();
              http_x++;
              data_size--;
            }
            else
            {
              delay(1);
            }
          }
          while(data_size > 0);
          data[http_x] = '\0';
        }
      }
      else if ((aux_str[0] == 'D') && (http_status == 2))
      {
        // Data packet with header
        while(Serial.available()<4);
        Serial.read();  // A
        Serial.read();  // T
        Serial.read();  // A
        Serial.read();  // ,

        // Reads the packet size
        x=0;
        do{
          while(Serial.available()==0);
          aux_str[x] = Serial.read();
          x++;
        }
        while((aux_str[x-1] != '\r') && (aux_str[x-1] != '\n'));

        aux_str[x-1] = '\0';
        data_size = atoi(aux_str);

        do{
          if(Serial.available() != 0){
            data[http_x] = Serial.read();
            http_x++;
          }
          else
          {
            delay(1);
          }
        }
        while(data_size > 0);
        data[http_x] = '\0';

      }
      else if (aux_str[0] == '0')
      {
        // end of the AT command
        http_status = 0;
      }
      else
      {
        // unknow response
        http_status = 4;
        Serial.print(char(aux_str[0]));
        Serial.print(char(Serial.read()));
        Serial.print(char(Serial.read()));
        Serial.print(char(Serial.read()));
        Serial.print(char(Serial.read()));
        Serial.print(char(Serial.read()));
        Serial.print(char(Serial.read()));
        Serial.print(char(Serial.read()));
        Serial.print(char(Serial.read()));
      }			
    }		
  }

  previous = millis() - previous;
  
  Serial.println(previous, DEC);
  if (http_status == 0)
  {
    Serial.print(F("HTTP data: "));
    Serial.println(data);
  }
  else
  {
    Serial.print(F("http_status: "));
    Serial.println(http_status, DEC);
  }



  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_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 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_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 is in the response of the module
      if (strstr(response, expected_answer1) != NULL)
      {
        answer = 1;
      }
      // check if the desired answer 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:
/*
 *  Description: This example shows the AT commands (and the answers of the module)
 *  used to work with HTTP to do a GET method to our server in Libelium.
 *  For more information about the AT commands, refer to the AT command manual.
 *
 *  Copyright (C) 2013 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.
 *
 *  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 0.2
 *  Author: Alejandro Gallego & Victor Boria
 */

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

//Change here your data
const char pin_number[] = "****";
const char apn[] = "*********";
const char user_name[] = "*********";
const char password[] = "*********";

char url[ ] = "test.libelium.com";
int port = 80;
char request[ ] = "GET /test-get-post.php?a=1&b=2&c=3 HTTP/1.1\r\nHost: test.libelium.com\r\nContent-Length: 0\r\n\r\n";

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_answer1, unsigned int timeout);
void power_on();

int8_t answer;
int onModulePin = 2, aux;
int data_size = 0;
int end_file = 0;
char aux_str[100];
char data[600];
int http_x;
int http_status; // 0: end, 1 waiting data with header, 2 waiting data without header, 3 timeout waiting data, 4 unknow response
int x = 0;
long previous;

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_number);
  sendATcommand(aux_str, "OK", 2000);

  delay(3000);

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

  // sets APN, user name and password
  sprintf(aux_str, "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
  sendATcommand(aux_str, "OK", 2000);

  sprintf(aux_str, "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
  sendATcommand(aux_str, "OK", 2000);
}

void loop() {

  // request the url
  previous = millis();
  sprintf(aux_str, "AT+CHTTPACT=\"%s\",%d", url, port);
  answer = sendATcommand(aux_str, "+CHTTPACT: REQUEST", 60000);

  // Sends the request
  Serial.println(request);
  // Sends <Ctrl+Z>
  Serial.write(0x1A);
  http_status = 1;

  while ((http_status == 1) || (http_status == 2))
  {
    answer = sendATcommand("", "+CHTTPACT: ", 60000);
    if (answer == 0)
    {
      if (http_status == 1)
      {
        http_status = 3;
      }
      if (http_status == 2)
      {
        http_status = 5;
      }
    }
    else
    {
      // answer == 1
      while (Serial.available() == 0);
      aux_str[0] = Serial.read();

      if ((aux_str[0] == 'D') && (http_status == 1))
      {
        // Data packet with header
        while (Serial.available() < 4);
        Serial.read();  // A
        Serial.read();  // T
        Serial.read();  // A
        Serial.read();  // ,

        // Reads the packet size
        x = 0;
        do {
          while (Serial.available() == 0);
          aux_str[x] = Serial.read();
          x++;
        }
        while ((aux_str[x - 1] != '\r') && (aux_str[x - 1] != '\n'));

        aux_str[x - 1] = '\0';
        data_size = atoi(aux_str);

        // Now, search the end of the HTTP header (\r\n\r\n)
        do {
          while (Serial.available() < 3);

          data_size--;
          if (Serial.read() == '\r')
          {
            data_size--;
            if (Serial.read() == '\n')
            {
              data_size--;
              if (Serial.read() == '\r')
              {
                data_size--;
                if (Serial.read() == '\n')
                {
                  // End of the header found
                  http_status = 2;
                }
              }
            }
          }
        }
        while ((http_status == 1) && (data_size > 0));

        if (http_status == 2)
        {
          // Reads the data
          http_x = 0;
          do {
            if (Serial.available() != 0) {
              data[http_x] = Serial.read();
              http_x++;
              data_size--;
            }
            else
            {
              delay(1);
            }
          }
          while (data_size > 0);
          data[http_x] = '\0';
        }
      }
      else if ((aux_str[0] == 'D') && (http_status == 2))
      {
        // Data packet with header
        while (Serial.available() < 4);
        Serial.read();  // A
        Serial.read();  // T
        Serial.read();  // A
        Serial.read();  // ,

        // Reads the packet size
        x = 0;
        do {
          while (Serial.available() == 0);
          aux_str[x] = Serial.read();
          x++;
        }
        while ((aux_str[x - 1] != '\r') && (aux_str[x - 1] != '\n'));

        aux_str[x - 1] = '\0';
        data_size = atoi(aux_str);

        do {
          if (Serial.available() != 0) {
            data[http_x] = Serial.read();
            http_x++;
          }
          else
          {
            delay(1);
          }
        }
        while (data_size > 0);
        data[http_x] = '\0';

      }
      else if (aux_str[0] == '0')
      {
        // end of the AT command
        http_status = 0;
      }
      else
      {
        // unknow response
        http_status = 4;
      }
    }
  }

  previous = millis() - previous;


  printf("Response time: %u seconds\n", previous/1000);

  if (http_status == 0)
  {
    printf("HTTP data: %s\n", data);
  }
  else
  {
    printf("http_status: %d\n", http_status);
  }


  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_answer1, unsigned int timeout)
{

  uint16_t x = 0,  answer = 0;
  char response[1000];
  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();
      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[400];
  unsigned long previous;

  memset(response, '\0', sizeof(response));    // 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();
      //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;
      }
      // check if the desired answer 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);
}
        

HTTPS

Arduino:

Code:
/*
 *  Description: This example shows how to do a GET method. So the buffer of 
 *  is limited, we recommend to use the GET method with short answer for the
 *  requested webs. 
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with HTTPS. For more information about the AT commands, 
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2013 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. 
 *  
 *  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 0.2
 *  Author: Alejandro Gallego & Victor Boria
 */

//Change here your data
const char pin_number[] = "****";
const char apn[] = "*********";
const char user_name[] = "*********";
const char password[] = "*********";
char url[ ]="www.google.com";
int port= 443;
char request[ ]="GET /index.html HTTP/1.1\r\nHost: www.mywebsite.com\r\nContent-Length: 0\r\n\r\n";

int8_t answer;
int onModulePin = 2, aux;
int data_size = 0;
int end_file = 0;
char aux_str[100];
char data[250];
int x = 0;
long previous;


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_number);
  sendATcommand(aux_str, "OK", 2000);

  delay(3000);

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

  // sets APN, user name and password
  sprintf(aux_str, "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
  sendATcommand(aux_str, "OK", 2000);

  sprintf(aux_str, "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
  sendATcommand(aux_str, "OK", 2000);
}
void loop(){


  // gets the SSL stack
  answer = sendATcommand("AT+CHTTPSSTART", "OK", 5000);
  if (answer == 1)
  { 
    // Opens the HTTP session
    sprintf(aux_str, "AT+CHTTPSOPSE=\"%s\",%d", url, port);
    answer = sendATcommand(aux_str, "OK", 30000);
    if (answer == 1)
    {
      // Stores and sends the request
      sprintf(aux_str, "AT+CHTTPSSEND=%d", strlen(request));
      answer = sendATcommand(aux_str, ">", 5000);
      if (answer == 1)
      {
        answer = sendATcommand(request, "OK", 5000);  
        if (answer == 1)
        {   
          // request the url
          answer = sendATcommand("AT+CHTTPSSEND", "OK", 5000);

          if (answer == 1)
          {        
            answer = sendATcommand("AT+CHTTPSRECV=1", "+CHTTPSRECV: DATA,", 60000);

            x=0;
            do{
              if (answer == 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
              {
                Serial.println("Error getting the url");
                data_size = 0;
              }

              answer = sendATcommand2("", "+CHTTPSRECV: DATA,", "+CHTTPSRECV:0", 20000);

            }
            while (answer != 1);

            if (answer == 2)
            {
              Serial.print("Data received:");
              Serial.println(data);
            }
            else
            {
              Serial.println("Error getting data");
            }
          }
          else
          {
            Serial.println("Error waiting the request");    
          }
        }
        else
        {
          Serial.println("Error waiting the request");    
        }

      }
      else
      {
        Serial.println("Error waiting the request");    
      }
      sendATcommand("AT+CHTTPSCLSE", "OK", 5000);
    }
    else
    {
      Serial.println("Error opening the HTTPS session");
    }
    sendATcommand("AT+CHTTPSSTOP", "OK", 5000);
  }
  else
  {
    Serial.println("Error getting the SSL stack");
  }

  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_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 is in the response of the module
      if (strstr(response, expected_answer1) != NULL)    
      {
        answer = 1;
      }
      // check if the desired answer 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:
/*
 *  Description: This example shows how to do a GET method. So the buffer of
 *  is limited, we recommend to use the GET method with short answer for the
 *  requested webs.
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with HTTPS. For more information about the AT commands,
 *  refer to the AT command manual.
 *
 *  Copyright (C) 2013 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.
 *
 *  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 0.2
 *  Author: Alejandro Gallego & Victor Boria
 */

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

//Change here your data
char url[ ] = "www.google.com";
int port = 443;
char request[ ] = "GET /index.html HTTP/1.1\r\nHost: www.mywebsite.com\r\nContent-Length: 0\r\n\r\n";

const char pin[] = "your_pin";
const char apn[] = "your_apn";
const char user_name[] = "your_user_name";
const char password[] = "your_password";

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

int8_t client;
int8_t answer;
int onModulePin = 2, aux;
int x = 0;
char data[250];
unsigned long previous;
int data_size = 0;
int end_file = 0;


char aux_str[1000];



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);
  printf("Connecting to the network\n");

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

  printf("Succesfully connected to the network\n");

  // sets APN, user name and password
  snprintf(aux_str, sizeof(aux_str), "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
  sendATcommand(aux_str, "OK", 2000);

  snprintf(aux_str, sizeof(aux_str), "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
  sendATcommand(aux_str, "OK", 2000);
}

void loop() {

  // gets the SSL stack
  answer = sendATcommand("AT+CHTTPSSTART", "OK", 5000);
  if (answer == 1)
  {
    // Opens the HTTP session
    sprintf(aux_str, "AT+CHTTPSOPSE=\"%s\",%d", url, port);
    answer = sendATcommand(aux_str, "OK", 30000);
    if (answer == 1)
    {
      // Stores and sends the request
      sprintf(aux_str, "AT+CHTTPSSEND=%d", strlen(request));
      answer = sendATcommand(aux_str, ">", 5000);
      if (answer == 1)
      {
        answer = sendATcommand(request, "OK", 5000);
        if (answer == 1)
        {
          // request the url
          answer = sendATcommand("AT+CHTTPSSEND", "OK", 5000);

          if (answer == 1)
          {
            answer = sendATcommand("AT+CHTTPSRECV=1", "+CHTTPSRECV: DATA,", 60000);

            x = 0;
            do {
              if (answer == 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: %s\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
              {
                printf("Error getting the url\n");
                data_size = 0;
              }

              answer = sendATcommand2("", "+CHTTPSRECV: DATA,", "+CHTTPSRECV:0", 20000);

            }
            while (answer != 1);

            if (answer == 2)
            {
              printf("Data received: %s\n", data);
            }
            else
            {
              printf("Error getting data\n", data);
            }
          }
          else
          {
            printf("Error waiting the request\n", data);
          }
        }
        else
        {
          Serial.println("");
          printf("Error waiting the request\n");
        }

      }
      else
      {
        printf("Error waiting the request\n");
      }
      sendATcommand("AT+CHTTPSCLSE", "OK", 5000);
    }
    else
    {
      printf("Error opening the HTTPS session\n");
    }
    sendATcommand("AT+CHTTPSSTOP", "OK", 5000);
  }
  else
  {
    printf("Error getting the SSL stack\n");
  }

  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_answer1, unsigned int timeout)
{

  uint16_t x = 0,  answer = 0;
  char response[1000];
  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();
      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);

  //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();
      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 answer 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+CHTTPACT=”***”,&&   Launches a HTTP operation . *** is the server address and && is the port.
     
AT+CHTTPSSTART OK Acquires HTTPS protocol stack.
AT+CHTTPSSTOP OK Releases HTTPS protocol stack.
AT+CHTTPSOPSE OK Opens a new HTTPS session.
AT+CHTTPSCLSE OK Closes the opened HTTPS session.
AT+CHTTPSSEND=*   Sends HTTPS request. * is the length of the data in the sending buffer.
AT+CHTTPSRECV=*   Receives HTTPS response after sending HTTPS request.

16. Fritzing Libraries

The new 3G shield for Arduino enables the connectivity to high speed WCDMA and HSPA cellular networks in order to make possible the creation of the next level of worldwide interactivity projects inside the new "Internet of Things" era.

You can download our Fritzing libraries from this area.

17. Video-Tutorial

Here's an explanatory video, which shows the whole process developed in this tutorial:

Check the GPS+PIC Code here:

Arduino:

Code:
/*
 *  Description: This example shows how to take a picture from the camera,
 *  get GPS position and send an email with all this data.
 *
 *  Copyright (C) 2013 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.
 *
 *  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
 *  Author: Alejandro Gallego & Victor Boria
 */

//Write here you SIM card data
const char pin_number[] = "****";
const char apn[] = "*********";
const char user_name[] = "*********";
const char password[] = "*********";

//Write here you server and account data
const char smtp_server[ ] = "*********";      // SMTP server
const char smtp_user_name[ ] = "*********";   // SMTP user name
const char smtp_password[ ] = "*********";    // SMTP password
const char smtp_port[ ] = "***";              // SMTP server port

//Write here your information about sender, direcctions and names
const char sender_address[ ] = "*********";    // Sender address
const char sender_name[ ] = "*********";       // Sender name

const char to_address[ ] = "*********";        // Recipient address
const char to_name[ ] = "*********";           // Recipient name

//Write here the subject and body of the email
char subject[ ] = "GPS+PIC";

int8_t answer, counter;
int onModulePin = 2;    // the pin to switch on the module (without press on button)
char picture_name[25];
char aux_str[128];
int GPS_retries;
char gps_data[100];


void setup() {
  pinMode(onModulePin, OUTPUT);
  Serial.begin(115200);      // UART baud rate

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

  delay(3000);

  //Use this command if you want to delete the files in C:
  //sendATcommand("AT+FSDEL=*.*", "OK", 3000);

  get_GPS();        // Waits for GPS data
  take_picture();   // Takes a picture
  send_email();     // Sends an email with coordinates and picture
}

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


void get_GPS() {

  // starts GPS session in stand alone mode
  answer = sendATcommand("AT+CGPS=1,1", "OK", 1000);
  if (answer == 0)
  {
    Serial.println("Error starting the GPS");
    Serial.println("The code stucks here!!");
    while (1);
  }

  GPS_retries = 50;
  do {
    answer = sendATcommand("AT+CGPSINFO", "+CGPSINFO:", 1000);  // request info from GPS
    if (answer == 1)
    {

      counter = 0;
      do {
        while (Serial.available() == 0);
        gps_data[counter] = Serial.read();
        counter++;
      }
      while (gps_data[counter - 1] != '\r');
      gps_data[counter - 1] = '\0';
      if (gps_data[0] == ',')
      {
        Serial.println("No GPS data available");
      }
      else
      {
        Serial.print("GPS data:");
        Serial.println(gps_data);
        Serial.println("");
      }

    }
    else
    {
      Serial.println("Error");
    }
    delay(1000);
    GPS_retries--;
  }
  while ((GPS_retries > 0) && (gps_data[0] == ','));



  delay(5000);
}




void take_picture() {

  // Starts the camera
  answer = sendATcommand2("AT+CCAMS", "OK", "CAMERA NO SENSOR", 3000);
  if (answer == 1)
  {
    // Sets resolution (Old camera)
    //sendATcommand2("AT+CCAMSETD=640,480", "OK", "ERROR", 2000);

    // Sets resolution (New camera)
    sendATcommand2("AT+CCAMSETD=1600,1200", "OK", "ERROR", 2000);

    //  sendATcommand("AT+FSLOCA=1", "OK", 3000);
    // Takes a picture, but not saved it
    answer = sendATcommand2("AT+CCAMTP", "OK", "ERROR", 5000);
    delay(1000);
    if (answer == 1)
    {
      // Saves the picture into C:/Picture
      answer = sendATcommand2("AT+CCAMEP", "C:/Picture/", "ERROR", 2000);

      if (answer == 1)
      {
        memset(picture_name, 0x00, sizeof(picture_name));
        counter = 0;
        while (Serial.available() == 0);
        do {
          picture_name[counter] = Serial.read();
          counter++;
          while (Serial.available() == 0);
        } while (picture_name[counter - 1] != 0x0D);

        picture_name[counter - 1] = '\0';

        Serial.print("Picture name: ");
        Serial.println(picture_name);

        sendATcommand2("AT+CCAME", "OK", "OK", 2000);

      }
      else
      {
        Serial.println("Error saving the picture");
      }
    }
    else if (answer == 2)
    {
      Serial.println("Camera invalid state");
    }
    else
    {
      Serial.println("Error taking the picture");
    }
  }
  else if (answer == 2)
  {
    Serial.println("Camera not detected");
  }
  else
  {
    Serial.println("Error starting the camera");
  }

}

void send_email() {

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

  delay(3000);

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

  // sets the SMTP server and port
  sprintf(aux_str, "AT+SMTPSRV=\"%s\",%s", smtp_server, smtp_port);
  sendATcommand(aux_str, "OK", 2000);

  // sets user name and password
  sprintf(aux_str, "AT+SMTPAUTH=1,\"%s\",\"%s\"", smtp_user_name, smtp_password);
  sendATcommand(aux_str, "OK", 2000);

  // sets sender adress and name
  sprintf(aux_str, "AT+SMTPFROM=\"%s\",\"%s\"", sender_address, sender_name);
  sendATcommand(aux_str, "OK", 2000);

  // sets sender adress and name
  sprintf(aux_str, "AT+SMTPRCPT=1,0,\"%s\",\"%s\"", to_address, to_name);
  sendATcommand(aux_str, "OK", 2000);

  // subjet of the email
  sprintf(aux_str, "AT+SMTPSUB=\"%s\"", subject);
  sendATcommand(aux_str, "OK", 2000);

  // body of the email
  sprintf(aux_str, "AT+SMTPBODY=\"%s\"", gps_data);
  sendATcommand(aux_str, "OK", 2000);

  answer =  sendATcommand("AT+FSCD=Picture", "OK", 2000);

  Serial.println(answer, DEC);

  sprintf(aux_str, "AT+SMTPFILE=1,\"%s\"", picture_name);
  answer = sendATcommand(aux_str, "OK", 2000);

  Serial.println(answer, DEC);

  // sets APN, user name and password
  sprintf(aux_str, "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
  sendATcommand(aux_str, "OK", 2000);

  sprintf(aux_str, "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
  sendATcommand(aux_str, "OK", 2000);

  delay(10000);

  Serial.println("Sending email...");
  // sends the email and waits the answer of the module
  answer = sendATcommand2("AT+SMTPSEND", "+SMTP: SUCCESS", "NETWORK ERROR", 60000);
  if (answer == 1)
  {
    Serial.println("Done!");
  }
  else if (answer == 2)
  {
    Serial.println("Error2");
  }

  else
  {

    Serial.println("Error");
  }

}


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 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_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 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:
/*
 *  Description: This example shows how to take a picture from the camera,
 *  get GPS position and send an email with all this data.

 *  Copyright (C) 2012 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.
 *
 *  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
 *  Author: Alejandro Gállego & Victor Boria
 */

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

//Write here you SIM card data
const char pin_number[] = "****";
const char apn[] = "*********";
const char user_name[] = "*********";
const char password[] = "*********";

//Write here you server and account data
const char smtp_server[ ] = "*********";      // SMTP server
const char smtp_user_name[ ] = "*********";   // SMTP user name
const char smtp_password[ ] = "*********";    // SMTP password
const char smtp_port[ ] = "***";              // SMTP server port

//Write here your information about sender, direcctions and names
const char sender_address[ ] = "*********";    // Sender address
const char sender_name[ ] = "*********";       // Sender name

const char to_address[ ] = "*********";        // Recipient address
const char to_name[ ] = "*********";           // Recipient name

//Write here the subject and body of the email
char subject[ ] = "GPS+PIC";

int8_t answer, counter;
int onModulePin = 2;    // the pin to switch on the module (without press on button)
char aux_str[1280];
char picture_name[25];
int GPS_retries;
char gps_data[100];

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


void setup() {

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

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

  delay(3000);

  //Use this command if you want to delete the files in C:
  //sendATcommand("AT+FSDEL=*.*", "OK", 3000);

  get_GPS();       // Waits for GPS data
  take_picture();  // Takes a picture
  send_email();    // Sends an email with coordinates and picture
}

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

}

void get_GPS() {
  // starts GPS session in stand alone mode
  answer = sendATcommand("AT+CGPS=1,1", "OK", 1000);
  if (answer == 0)
  {
    printf("Error starting the GPS. The code stucks here!!\n");
    while (1);
  }

  GPS_retries = 50;
  do {
    answer = sendATcommand("AT+CGPSINFO", "+CGPSINFO:", 1000);  // request info from GPS
    if (answer == 1)
    {

      counter = 0;
      do {
        while (Serial.available() == 0);
        gps_data[counter] = Serial.read();
        counter++;
      }
      while (gps_data[counter - 1] != '\r');
      gps_data[counter - 1] = '\0';
      if (gps_data[0] == ',')
      {
        printf("No GPS data available\n");
      }
      else
      {
        printf("GPS data: %s\n", gps_data);
      }

    }
    else
    {
      printf("Error\n");
    }
    delay(1000);
    GPS_retries--;
  } while ((GPS_retries > 0) && (gps_data[0] == ','));



  delay(5000);

}


void take_picture() {
  // Starts the camera
  answer = sendATcommand2("AT+CCAMS", "OK", "CAMERA NO SENSOR", 3000);
  if (answer == 1)
  {
    // Sets resolution (Old camera)
    //sendATcommand2("AT+CCAMSETD=640,480", "OK", "ERROR", 2000);

    // Sets resolution (New camera)
    sendATcommand2("AT+CCAMSETD=1600,1200", "OK", "ERROR", 2000);
	
	printf("Taking photo...\n");
    // Takes a picture, but not saved it
    answer = sendATcommand2("AT+CCAMTP", "OK", "ERROR", 5000);
    delay(1000);
    if (answer == 1)
    {
      // Saves the picture into C:/Picture
      answer = sendATcommand2("AT+CCAMEP", "C:/Picture/", "ERROR", 2000);

      if (answer == 1)
      {
        memset(picture_name, 0x00, sizeof(picture_name));
        counter = 0;
        while (Serial.available() == 0);
        do {
          picture_name[counter] = Serial.read();
          counter++;
          while (Serial.available() == 0);
        } while (picture_name[counter - 1] != 0x0D);

        picture_name[counter - 1] = '\0';

        printf("Picture name: %s\n", picture_name);

        sendATcommand2("AT+CCAME", "OK", "OK", 2000);

      }
      else
      {

        printf("Error saving the picture\n");
      }
    }
    else if (answer == 2)
    {
      printf("Camera invalid state\n");
    }
    else
    {
      printf("Error taking the picture\n");
    }
  }
  else if (answer == 2)
  {
    printf("Camera not detected\n");
  }
  else
  {
    printf("Error starting the camera\n");
  }

}

void send_email() {
  //sets the PIN code
  sprintf(aux_str, "AT+CPIN=%s", pin_number);
  sendATcommand(aux_str, "OK", 2000);

  delay(3000);

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

  // sets the SMTP server and port
  sprintf(aux_str, "AT+SMTPSRV=\"%s\",%s", smtp_server, smtp_port);
  sendATcommand(aux_str, "OK", 2000);

  // sets user name and password
  sprintf(aux_str, "AT+SMTPAUTH=1,\"%s\",\"%s\"", smtp_user_name, smtp_password);
  sendATcommand(aux_str, "OK", 2000);

  // sets sender adress and name
  sprintf(aux_str, "AT+SMTPFROM=\"%s\",\"%s\"", sender_address, sender_name);
  sendATcommand(aux_str, "OK", 2000);

  // sets sender adress and name
  sprintf(aux_str, "AT+SMTPRCPT=1,0,\"%s\",\"%s\"", to_address, to_name);
  sendATcommand(aux_str, "OK", 2000);

  // subjet of the email
  sprintf(aux_str, "AT+SMTPSUB=\"%s\"", subject);
  sendATcommand(aux_str, "OK", 2000);

  // body of the email
  sprintf(aux_str, "AT+SMTPBODY=\"%s\"", gps_data);
  sendATcommand(aux_str, "OK", 2000);

  //It's normal to receive an error in this instruction if you are already in this folder
  sendATcommand("AT+FSCD=Picture", "OK", 2000);

  sprintf(aux_str, "AT+SMTPFILE=1,\"%s\"", picture_name);
  sendATcommand(aux_str, "OK", 2000);

  // sets APN, user name and password
  sprintf(aux_str, "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
  sendATcommand(aux_str, "OK", 2000);

  sprintf(aux_str, "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
  sendATcommand(aux_str, "OK", 2000);

  delay(1000);

  printf("Sending email...\n");

  // sends the email and waits the answer of the module
  answer = sendATcommand("AT+SMTPSEND", "+SMTP: SUCCESS", 60000);
  if (answer == 1)
  {
    printf("Done!\n");
  }
  else
  {
    printf("Error\n");
  }

}




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

  uint16_t x = 0,  answer = 0;
  char response[1000];
  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();
      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);

  //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();
      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 answer with time out
  }
  while ((answer == 0) && ((millis() - previous) < timeout));

  return answer;
}


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


        



If you are interested in Internet of Things (IoT) or M2M projects check our open source sensor platform Waspmote which counts with more than 100 sensors available to use 'off the shelf', a complete API with hundreds of ready to use codes and a low consumption mode of just 0.7µA to ensure years of battery life.

Know more at:

Get the Starter Kits at: