Taillieu.Info

More Than a Hobby..

Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in /customers/3/2/5/taillieu.info/httpd.www/templates/taillieuinfo_joomla3_rev1/functions.php on line 194

ESP8266

 https://nurdspace.nl/ESP8266#Technical_Overview

 

ESP8266
ESP8266.jpg
Participants DreamerZarya
Skills ElectronicsSoftware
Status Getting parts
Niche Electronics
Purpose Education
Tool No
Location  
Cost about 5 dollar per module
Tool category  

ESP8266 

{{#if:No | [[Tool Owner::{{{ProjectParticipants}}} | }} {{#if:No | [[Tool Cost::about 5 dollar per module | }}

Building the gcc toolchain

have a look at the github wiki https://nurdspace.nl/skins/gumax/lock_icon.gif) 100% 50% no-repeat;">https://github.com/esp8266/esp8266-wiki/wiki

Code examples

have a look at the github wiki https://nurdspace.nl/skins/gumax/lock_icon.gif) 100% 50% no-repeat;">https://github.com/esp8266/esp8266-wiki/wiki

Running the module

    https://nurdspace.nl/skins/gumax/arrow.gif);">
  • The modules pins only allow 3.3v (use a multi meter to check your serial lines if you are not sure)
  • Connect CH_PD to VCC to make it boot

Uploading code

    https://nurdspace.nl/skins/gumax/arrow.gif);">
  • The modules pins only allow 3.3v (use a multi meter to check your serial lines if you are not sure)

see https://nurdspace.nl/skins/gumax/lock_icon.gif) 100% 50% no-repeat;">https://github.com/esp8266/esp8266-wiki/wiki/Uploading

links

Internal space links

External

Datasheet

Introduction

Yue Xin intelligent high performance wireless connectivity platform --ESCP SOC, designers bring the Gospel to the mobile platform, it At the lowest cost to provide maximum usability for WiFi capabilities embedded in other systems offer unlimited possibilities.

Technical Overview

ESP8266 is a complete and self-contained Wi-Fi network solutions that can carry software applications, or through Another application processor uninstall all Wi-Fi networking capabilities. ESP8266 when the device is mounted and as the only application of the application processor, the flash memory can be started directly from an external Move. Built-in cache memory will help improve system performance and reduce memory requirements. Another situation is when wireless Internet access assume the task of Wi-Fi adapter, you can add it to any microcontroller-based design, the connection is simple, just by SPI / SDIO interface or central processor AHB bridge interface. Processing and storage capacity on ESP8266 powerful piece, it can be integrated via GPIO ports sensors and other applications specific equipment to achieve the lowest early in the development and operation of at least occupy system resources. The ESP8266 highly integrated chip, including antenna switch balun, power management converter, so with minimal external circuitry, and includes front-end module, including the entire solution designed to minimize the space occupied by PCB. The system is equipped with ESP8266 manifested leading features are: energy saving VoIP quickly switch between the sleep / wake patterns, with low-power operation adaptive radio bias, front-end signal processing functions, troubleshooting and radio systems coexist characteristics eliminate cellular / Bluetooth / DDR / LVDS / LCD interference.

Characteristics

    https://nurdspace.nl/skins/gumax/arrow.gif);">
  • 802.11 b / g / n
  • Wi-Fi Direct (P2P), soft-AP
  • Built-in TCP / IP protocol stack
  • Built-in TR switch, balun, LNA, power amplifier and matching network
  • Built-in PLL, voltage regulator and power management components
  • 802.11b mode + 19.5dBm output power
  • Built-in temperature sensor
  • Support antenna diversity
  • off leakage current is less than 10uA
  • Built-in low-power 32-bit CPU: can double as an application processor
  • SDIO 2.0, SPI, UART
  • STBC, 1x1 MIMO, 2x1 MIMO
  • A-MPDU, A-MSDU aggregation and the 0.4 Within wake
  • 2ms, connect and transfer data packets
  • standby power consumption of less than 1.0mW (DTIM3)

Schema

Esp8266 schema.png

Ultra-low power technology

ESP8266 specifically for mobile devices, wearable electronics and networking applications design and make the machine to achieve the lowest energy consumption, together with several other patented technology. This energy-efficient construction in three modes: active mode, sleep mode and deep sleep mode type. When ESP8266 using high-end power management technology and logic systems to reduce non-essential functions of the power conversion regulate sleep patterns and work modes, in sleep mode, it consumes less than the current 12uA, is connected, it consumes less power to 1.0mW (DTIM = 3) or 0.5mW (DTIM = 10). Sleep mode, only calibrated real-time clock and watchdog in working condition. Real-time clock can be programmed to wake ESP8266 within a specific period of time. Through programming, ESP8266 will automatically wake up when detected certain to happen. ESP8266 automatic wake-up in the shortest time, this feature can be applied to the SOC for mobile devices, so before you turn Wi- Fi SOC are in a low-power standby mode. To meet the power requirements of mobile devices and wearable electronics products, ESP8266 at close range when the PA output power can be reduced through software programming to reduce overall power consumption in order to adapt to different applications.

Maximum integration

ESP8266 integrates the most critical components on the board, including power management components, TR switch, RF balun, a peak power of + 25dBm of PA, therefore, ESP8266 only guarantee the lowest BOM cost, and easy to be embedded in any system. ESP8266 BOM is the only external resistors, capacitors, and crystal.

ESP8266 application subject

    https://nurdspace.nl/skins/gumax/arrow.gif);">
  • Smart Power Plug
  • Home Automation
  • mesh network
  • industrial wireless control
  • Baby Monitor
  • Network Camera
  • sensor networks
  • wearable electronics
  • wireless location-aware devices
  • Security ID tag
  • wireless positioning system signals

Specifications

Power

The following data are based on a 3.3V power supply, ambient temperature 25C and use the internal regulator measured. [1] All measurements are made in the absence of the SAW filter, the antenna interface is completed. [2] all transmit data based on 90% duty cycle, continuous transmission mode in the measured.

ModeMinTypicalMaxUnits
802.11b, CCK 1Mbps, POUT=+19.5dBm   215   mA
802.11b, CCK 11Mbps, POUT=+18.5dBm   197   mA
802.11g, OFDM 54Mbps, POUT=+16dBm   145   mA
802.11n, MCS7, POUT =+14dBm   135   mA
802.11b, packet size of 1024 bytes, -80dBm   60   mA
802.11b, packet size of 1024 bytes, -70dBm   60   mA
802.11b, packet size of 1024 bytes, -65dBm   62   mA
Standby   0.9   uA
Deep sleep   10   mA
Saving mode DTIM 1   1.2   mA
Saving mode DTIM 3   0.86   mA
Shutdown   0.5   uA

RF specifications

The following data is at room temperature, the voltage of 3.3V and 1.1V, respectively, when measured

DescriptionMinTypicalMaxUnits
Input Frequency 2412   2484 MHz
Input resistance   50   Ω
Input reflection     -10 dB
At 72.2Mbps, PA output power 14 15 16 dBm
11b mode, PA output power 17.5 18.5 19.5 dBm
Sensitivity    
CCK, 1Mbps    -98   dBm
CCK, 11Mbps    -91   dBm
6Mbps (1/2 BPSK)    -93   dBm
54Mbps (3/4 64-QAM)    -75   dBm
HT20, MCS7 (65Mbps, 72.2Mbps)     -71   dBm
Adjacent suppression    
OFDM, 6Mbps   37   dB
OFDM, 54Mbps   21   dB
HT20, MCS0   37   dB
HT20, MCS7   20   dB

CPU and memory

CPU Interface

The chip embedded in an ultra-low-power 32-bit micro-CPU, with 16 compact mode. Can be connected to the CPU via the following interfaces:

    https://nurdspace.nl/skins/gumax/arrow.gif);">
  • connecting storage controllers can also be used to access external code memory RAM / ROM interface (iBus)
  • Also attached storage controller data RAM interface (dBus)
  • Access Register of AHB interface
  • JTAG debug interface

Storage Controller

Storage controller contains ROM and SRAM. CPU can iBus, dBus and AHB interface to access the storage controller. Any one of these interfaces can apply for access to ROM or RAM cells, memory arbiter to determine the running order in the order of arrival.

AHB and AHB module

AHB module acts as arbiter, through the MAC, and SDIO host CPU control AHB interface. Since sending Address different, AHB data requests may arrive the following two slaves in one: APB module, or flash memory controller (usually in the case of off-line applications) to the received request is a high speed memory controllers often request, APB module receives register access is often Request. APB module acts as a decoder, but only you can access the ESP8266 main module programmable registers. Since the sending address different, APB request may reach the radio receiver, SI / SPI, hosts SDIO, GPIO, UART, real-time clock (RTC), MAC or digital baseband.

Interface

ESP 8266 contains multiple analog and digital interfaces, as follows:

Main SI / SPI control (optional)

Main Serial Interface (SI) can run at two, three, four-wire bus configuration, is used to control the EEPROM or other I2C / SPI devices. Multiple devices share the two-wire I2C bus. Multiple SPI devices to share the clock and data signals, and according to the chip select, each controlled by software alone GPIO pins. SPI can be used to control external devices, such as serial flash, audio CODEC or other slave devices, installation, effectively giving it three different pins, making it the standard master SPI device.

    https://nurdspace.nl/skins/gumax/arrow.gif);">
  • SPI_EN0
  • SPI_EN1
  • SPI_EN2

SPI slave is used as the primary interface, giving SPI master and slave SPI support. In the built-in applications, SPI_EN0 is used as an enable signal, the role of external serial flash, download firmware and / or MIB data to baseband. In host-based applications, the firmware and you can choose one MIB data downloaded via the host interface both. This pin is active low when not should be left unconnected. SPI_EN1 often used for user applications, such as controlling the built-in applications or external audio codec sensor ADC. This pin is active low when not should be left unconnected. SPI_EN2 often used to control the EEPROM, storing individual data (individual data), such as MIB information, MAC address, and calibration data, or for general purposes. This pin is active low when not should be left unconnected.

Esp8266 spi timing.png

General Purpose IO

A total of up to 16 GPIO pins. The firmware can assign them different functions. Each GPIO can be configured internal pullup / pulldown resistors available software registers sampled input, triggering edge or level CPU interrupt input, trigger level wake-up interrupt input, open-drain or complementary push-pull output drivers, software register output source or sigma-delta PWM DAC. These pins are multiplexed with other functions, such as the main interface, UART, SI, Bluetooth co-existence and so on.

Digital IO pins

Digital IO pad is two-way, three states. It includes a three-state control input and output buffers. In addition, for low-power operation, IO can be set to hold state. For example, when we reduce the chip's power consumption, all the output enable signal can be set to maintain a low-power state. Hold function can be selectively implanted IO in need. When the IO help internal and external circuit driving, hold function can be used to hold last state. Hold function to pin introduce some positive feedback. Therefore, the external drive pin must be stronger than the positive feedback. However, the required driving force size is still small, in the 5uA of.

VariablesSymbolMinMaxUnits
Input Low Voltage Vil -0.3 0.25xV10 V
Input High Voltage Vih 0.75xV10 3.6 V
Input leakage current IIL - 50 nA
Output Low Voltage VOL - 0.1xV10 V
Output High Voltage VOH 0.8xV10 - V
Input pin capacitance Cpad - 2 pF
VDDIO V10 1.7 3.6 V
Current Imax - 12 mA
Temperature Tamb -20 100 C

All digital IO pins must add an overvoltage protection circuit (snap back circuit) between the pin and ground. Usually bounce (snap back) voltage is about 6V, while maintaining the voltage is 5.8V. This prevents excessive voltage and generating ESD. Diodes also avoid reverse voltage output devices.

Firmware and software tools development kit

The firmware running on the ROM and SRAM chip, when the device is awake, firmware via SDIO sector Download the instructions from the host side. Firmware is fully compliant with 802.11 b / g / n / e / i WLAN MAC protocol and Wi-Fi Direct specification only supports basic services unit distributed control function (DCF) under (BSS) operation, but also follow the latest Wi-Fi P2P protocol to support P2P groups operating (P2P group operation). Low level protocol functions automatically run by ESP8266, such as

    https://nurdspace.nl/skins/gumax/arrow.gif);">
  • RTS / CTS
  • Confirm
  • fragmentation and reassembly
  • polymerization
  • frame package (802.11h / https://nurdspace.nl/skins/gumax/external.png) 100% 50% no-repeat;">RFC 1042)
  • automatic beacon monitoring / scanning
  • P2P WiFi direct

With P2P discovery procedures, passive or active scanning once in the host command start, it will be done automatically. Perform power management, interaction with the host at least, this way, the task of effectively minimized.

Features

Laboratory features of the software developer's kit is as follows:

    https://nurdspace.nl/skins/gumax/arrow.gif);">
  • 802.11 b / g / n / d / e / i / k / r support
  • Wi-Fi Direct (P2P) support
  • P2P discovery, P2P group master mode (Group Owner mode), P2P Power Management
  • Infrastructure Network (Infrastructure BSS) station (Station) mode / P2P mode / SoftAP mold
  • hardware accelerator
      https://nurdspace.nl/skins/gumax/arrow.gif);">
    • CCMP (CBC-MAC, counting mode)
    • TKIP (MIC, RC4) o WAPI (SMS4)
    • WEP (RC4)
    • CRC
    • WPA / WPA2 and WPS support
    • Other 802.11i security features:
  • Pre-Certification
  • TSN

Open interfaces  prepared for a variety of upper EAP authentication methods, such as:

    https://nurdspace.nl/skins/gumax/arrow.gif);">
  • TLS
  • PEAP
  • LEAP
  • SIM
  • AKA
  • 802.11n support (2.4GHz)
  • Support MIMO 1x1 and 2x1, STBC, A-MPDU and A-MSDU aggregation, 0.4s guard interval
  • WMM saving U-APSD
  • use with multi-queue QoS management, in line with 802.11e standard multimedia data traffic optimization methods
  • Follow the UMA, and certified by UMA
  • 802.1h / RFC1042 frame encapsulation
  • hash DMA data transfer operation, the CPU usage to a minimum
  • antenna diversity and choice (by software management hardware)
  • the clock / power gating and follow the 802.11 standard power management combined, according to the current connection, enter OK dynamically adjusted to achieve the lowest energy consumption
  • ratio can be adjusted to set an optimum algorithm for the missing data and the Tx power transfer rate based on the actual SNR and packet

Rate

    https://nurdspace.nl/skins/gumax/arrow.gif);">
  • MAC layer automatic retransmission and automatic response, to avoid packet loss occurs when the host is running slow
  • seamless roaming support
  • Configurable packet traffic arbitration and tailored, based on the slave processor design combining a series of Bluetooth chip vendors to provide flexible and precise time-Bluetooth coexistence support
  • support dual / single antenna Bluetooth coexistence with syncing WiFi / Bluetooth capability

Power Management

Chip can tune into the following states:

    https://nurdspace.nl/skins/gumax/arrow.gif);">
  • off (OFF): CHIP_PD pin is in a low power state. RTC failure. All registers are emptied.
  • deep sleep (DEEP_SLEEP): RTC open, other parts of the chip are closed. RTC internal recovery memory to save the basic WiFi connection information.
  • sleep (SLEEP): Only RTC running. Crystal oscillator stops. Any part of the wake (MAC, host, RTC timer, external interrupt) will make the wake of the chip.
  • Wake (WAKEUP): In this state, the system from a sleep state to start (PWR) status. Crystal oscillator and PLL are converted enabled state.

* on state (ON): High-speed clock can run, And sent to each clock control register is enabled Modules. Each module, including the CPU, including the implementation of relatively low-level clock gating. When the system works, you can WAITI instructions to turn off the CPU's internal clock.

Esp8266 power mgmt.png

Clock Management

High Frequency Clock

ESP8266 on high frequency clock is used to drive two Tx and Rx mixer, which is generated by the internal oscillator and an external oscillator. Crystal frequency between 26MHz to 52MHz float. Although the internal crystal oscillator of the calibration range of the crystal so that the clock generator to meet the conditions, but in general, the crystal quality is still obtained a proper phase noise factors to be considered. When the crystal is used, or because of the frequency offset, rather than the best choice for quality, the maximum capacity of the data processing system and will reduce the sensitivity of the wifi. Please refer to the following instructions to measure the frequency offset.

VariablesSymbolMinMaxUnits
Frequency Fxo 52 MHz
Load capacitance Cl   32 pF
Dynamic capacitance Cm 2 5 pF
Serial resistance Rs 0 65 Ω
Frequency tolerance Fxo -15 15 ppm
Frequency vs Temperature (-25C ~ 75C) Fxo,Temp -15 15 ppm

External Reference Requirements

At 26MHz external clock frequency between 52MHz. In order to make a well-functioning radio receiver, the clock will Must have the following characteristics:

VariablesSymbolMinMaxUnits
Clock amplitude Vxo 0.2 1 Vpp
External clock accuracy Fxo,EXT -15 15 ppm
Phase Noise @ 1kHz offset, 40MHz clock     -120 dBc/Hz
Phase Noise @ 10kHz offset, 40MHz clock     -130 dBc/Hz
Phase Noise @ 100kHz offset, 40MHz clock     -138 dBc/Hz

Radio receivers

ESP8266 radio receiver mainly includes the following modules:

    https://nurdspace.nl/skins/gumax/arrow.gif);">
  • 2.4GHz receiver
  • 2.4GHz transmitter
  • High-speed clock generator and crystal oscillator
  • Real-time clock
  • bias and regulators
  • Power Management

Channel Frequency

According IEEE802.11bgn standard, RF transceiver supports the following channels:

ChannelFreq.ChannelFreq.
1 2412 8 2447
2 2417 9 2452
3 2422 10 2457
4 2427 11 2462
5 2432 12 2467
6 2437 13 2472
7 2442 14 2484

2.4GHz receiver

2.4GHz RF signal receiver down into quadrature baseband signal, with two high-resolution, high-speed ADC and the latter into a digital signal. In order to accommodate different signal channels, a radio receiver integrated RF filters, automatic gain control (AGC), DC offset compensation circuit and a baseband filter.

2.4GHz transmitter

2.4 GHz transmitter orthogonal frequency baseband signals up to 2.4GHz, using high-power CMOS power amplifier to drive the antenna. Further use of the digital calibration improves the linearity of the power amplifier to achieve the average power of + 19dBm in 802.11b transmission, the transmission reaches + 16dBm 802.11n average power, features super. To offset defects in the radio receiver is also calibrated by other measures such as:

    https://nurdspace.nl/skins/gumax/arrow.gif);">
  • carrier leakage
  • I / Q phase matching, and
  • baseband nonlinear

This will reduce the time and equipment required for testing.

Clock generator

The clock generator generates the receiver and transmitter 2.4GHz clock signal all of its components are integrated on the chip, Include:

    https://nurdspace.nl/skins/gumax/arrow.gif);">
  • inductor
  • varactor
  • closed-loop filter

Clock generator contains a built-in calibration circuit and self-test circuitry. Clock phase and quadrature phase noise through the optimal calibration algorithm processing patent on the chip, in order to ensure that the receiver and transmitter to achieve the best performance.

AT Commands

Format

    https://nurdspace.nl/skins/gumax/arrow.gif);">
  • Baud rate at 57600
  • x is the commands
SetInquiryTestExecute
AT+<x>=<…> AT+<x>? AT+<x>=? AT+<x>
AT+CWMODE=<mode> AT+CWMODE? AT+CWMODE=? -
Set the network mode Check current mode Return which modes supported -

Commands

    https://nurdspace.nl/skins/gumax/arrow.gif);">
  • carefully there are must be no any spaces between the " and IP address or port
CommandsDescriptionTypeSet/ExecuteInquirytestParametersExamples
AT+RST restart the module basic - - - -
AT+CWMODE wifi mode wifi AT+CWMODE=<mode> AT+CWMODE? AT+CWMODE=? 1= Sta, 2= AP, 3=both
AT+CWJAP join the AP wifi AT+ CWJAP =<ssid>,< pwd > AT+ CWJAP? - ssid = ssid, pwd = wifi password
AT+CWLAP list the AP wifi AT+CWLAP      
AT+CWQAP quit the AP wifi AT+CWQAP - AT+CWQAP=?  
AT+ CWSAP set the parameters of AP wifi AT+ CWSAP= <ssid>,<pwd>,<chl>, <ecn> AT+ CWSAP?   ssid, pwd, chl = channel, ecn = encryption Connect to your router: :AT+CWJAP="YOURSSID","helloworld"; and check if connected: AT+CWJAP?
AT+ CIPSTATUS get the connection status TCP/IP AT+ CIPSTATUS      
AT+CIPSTART set up TCP or UDP connection TCP/IP 1)single connection (+CIPMUX=0) AT+CIPSTART= <type>,<addr>,<port>; 2) multiple connection (+CIPMUX=1) AT+CIPSTART= <id><type>,<addr>, <port> - AT+CIPSTART=? id = 0-4, type = TCP/UDP, addr = IP address, port= port Connect to another TCP server, set multiple connection first: AT+CIPMUX=1; connect: AT+CIPSTART=4,"TCP","X1.X2.X3.X4",9999
AT+CIPSEND send data TCP/IP 1)single connection(+CIPMUX=0) AT+CIPSEND=<length>; 2) multiple connection (+CIPMUX=1) AT+CIPSEND= <id>,<length>   AT+CIPSEND=?   send data: AT+CIPSEND=4,15 and then enter the data
AT+CIPCLOSE close TCP or UDP connection TCP/IP AT+CIPCLOSE=<id> or AT+CIPCLOSE   AT+CIPCLOSE=?  
AT+CIFSR Get IP address TCP/IP AT+CIFSR   AT+ CIFSR=?  
AT+ CIPMUX set mutiple connection TCP/IP AT+ CIPMUX=<mode> AT+ CIPMUX?   0 for single connection 1 for mutiple connection
AT+ CIPSERVER set as server TCP/IP AT+ CIPSERVER= <mode>[,<port> ]     mode 0 to close server mode, mode 1 to open; port = port turn on as a TCP server: AT+CIPSERVER=1,8888, check the self server IP address: AT+CIFSR=?
+IPD received data          

Pin Definition

There are multiple versions of the model, check the source where you bought the module.

GPRS/GSM Quadband Module for Arduino Tutorial (SIM900)

Tutorial Index

Go to IndexIntroduction

Ingredients:

Difficulty: Medium - medium

Preparation Time: 45 minutes

gprs_quadband_module
 

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

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

NOTE: If you are interested in Wireless Sensor Networks (WSN)M2M and the Internet of Things (IoT) projects check ournew open source sensor platformWaspmote which counts with more than 60 sensors available to use and a low consumption mode of just 0.07uA to ensure years of battery life. Know more at:

Go to IndexStep 1: The shield (hardware)

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

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

GPRS Shield diagram version 2:

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

gprs_diagram

GPRS Shield diagram version 1:

gprs_diagram

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

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

Go to IndexStep 2: Using GSM/GPRS module with AT commands

Important issues:

  • Use capital letters for AT commands.
  • Send CR (Carriage return) and LF (Line feed) after the AT command.
  • Place the serial communication jumpers in the right position.
  • Use an external power supply and place the power jumpers in the right position. If the shield is powered from the Arduino, the power jumper must be in Arduino 5V position. It the shield is powered from the Vin input (in the shield), the power jumper must be in Vext position.

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:

gprs_quadband_module

Connect the shield to the Arduino gateway.

gprs_quadband_module

Then connect the USB cable and the SIM card.

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

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

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

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

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: Factory baudrate setting is auto-bauding by default. Baudrate can be fixed using the command AT+IPR=baudrate . Allowed baudrates: 0 (Auto-bauding) , 1200 , 2400 , 4800 , 9600 , 19200 , 38400 , 57600 and 115200 ;

All the AT commands here

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.cpp (/arduino-1.0.X/hardware/arduino/cores/arduino):

#if (RAMEND < 1000) 
  #define SERIAL_BUFFER_SIZE 32 
#else 
  #define SERIAL_BUFFER_SIZE 256 
#endif

by

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

Go to IndexStep 3: Powering the board:

Some of the USB ports on computers are not able to give all the current the module needs to work, if your module goes down when it tries to connect to the network, you can use an external power supply (12V - 2A) on the Arduino.

Remember set the Arduino power jumper to EXT!!! (if you use Diecimila or older).

How to set the power jumper in the shield?.

If you want the shield takes power from Arduino => Set the jumper to Arduino 5V possition

If you want the shield takes power from an external supply => Set the jumper to V ext. possition

For powering the shield from external supply , you have to use V in ext. connector (Vin + GND).

If you use a power supply with output smaller than 2 A, you should add an extra capacitor for the power.

For example, a 220 uF electrolytic capacitor between 3.3V and GND.

Go to IndexStep 4: Using the shield in standalone mode - Calls

Originating and receiving voice calls

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

Hide 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 
 */
 
 
int8_t answer;
int onModulePin = 2;
int button = 12;
char aux_str[30];

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
    sendATcommand("AT+CPIN=****", "OK", 2000);
    
    delay(3000);
    
    Serial.println("Connecting to the network...");

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

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

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

}

void loop(){

}

void power_on(){

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

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

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

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


    x = 0;
    previous = millis();

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

    return answer;
}

To make a lost call next code is used.

Show 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 
 */
 
int8_t answer;
int onModulePin = 2;
int seconds = 20;
char aux_str[30];

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

void setup(){

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

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

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

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

}

void loop(){

}

void power_on(){

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

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

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

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


    x = 0;
    previous = millis();

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

    return answer;
}

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

Command summary

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

Go to IndexStep 5: Using the shield in standalone mode - Sending and receiving SMS

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

Show 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 
 */

int8_t answer;
int onModulePin= 2;
char aux_string[30];
char phone_number[]="*********";

void setup(){

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

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

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

}


void loop(){

}

void power_on(){

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

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

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

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


    x = 0;
    previous = millis();

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

    return answer;
}
Show 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 
 */

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

void setup(){

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

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

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


}


void loop(){

}

void power_on(){

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

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

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

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

    delay(100);

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

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


        x = 0;
    previous = millis();

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

    return answer;
}

Command summary

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

Go to IndexStep 6: Using the shield in standalone mode - FTP

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

Show Code
/*
 *  Description: This example shows how to upload and download files from a FTP 
 *  server. The example configures the module to use FTP funtions, uploads a file 
 *  to the FTP server and then downloads the content of the uploaded file and shows
 *  it. This example only shows the AT commands (and the answers of the module) 
 *  used to use the FTP funtion and how work the FTP functions. 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 
 */

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

char incoming_data[120];

char test_str[ ]= "0000000011111111222222223333333344444444555555556666666677777777000000001111111122222222333333334444";

int data_size, aux;


void setup(){

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


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

    delay(5000);

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

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

    configure_FTP();

    uploadFTP();

    downloadFTP();

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


void loop(){

}


void configure_FTP(){

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

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

}


void uploadFTP(){

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

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

void downloadFTP(){

    int x = 0;

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

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

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

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




void power_on(){

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


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

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

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

    delay(100);

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

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


        x = 0;
    previous = millis();

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

        return answer;
}

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

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

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

    delay(100);

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

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


        x = 0;
    previous = millis();

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

        return answer;
}

Command summary

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

Go to IndexStep 7: Using the shield in standalone mode - TCP and UDP

Single client

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

Show Code
/*
 *  Description: This example shows how to configure the GPRS module in single 
 *  client mode and open a TCP socket as client. This example only shows the 
 *  AT commands (and the answers of the module) used to open a TCP/UDP 
 *  connection. 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 
 */
 
int8_t answer;
int onModulePin= 2;
char aux_str[50];

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



void setup(){

    pinMode(onModulePin, OUTPUT);
    Serial.begin(115200);    
    
    Serial.println("Starting...");
    power_on();
    
    delay(3000);
    
    // sets the PIN code
    sendATcommand2("AT+CPIN=****", "OK", "ERROR", 2000);
    
    delay(3000);
    
    Serial.println("Connecting to the network...");

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

}


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

void power_on(){

    uint8_t answer=0;
    
    // checks if the module is started
    answer = sendATcommand2("AT", "OK", "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 = sendATcommand2("AT", "OK", "OK", 2000);    
        }
    }
    
}

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

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

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

    delay(100);

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

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

    x = 0;
    previous = millis();

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

    return answer;
}

Multiple client

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

Show Code
/*
 *  Description: This example shows how to configure the GPRS module in multi 
 *  client mode and open a TCP socket as client. This example only shows the 
 *  AT commands (and the answers of the module) used to open a TCP/UDP 
 *  connection. 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 
 */
 
 
int8_t answer;
int onModulePin= 2;
char aux_str[50];

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



void setup(){

    pinMode(onModulePin, OUTPUT);
    Serial.begin(115200);    
    
    Serial.println("Starting...");
    power_on();
    
    delay(3000);
    
    // sets the PIN code
    sendATcommand2("AT+CPIN=****", "OK", "ERROR", 2000);
    
    delay(3000);
    
    Serial.println("Connecting to the network...");

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

}


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

void power_on(){

    uint8_t answer=0;
    
    // checks if the module is started
    answer = sendATcommand2("AT", "OK", "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 = sendATcommand2("AT", "OK", "OK", 2000);    
        }
    }
    
}

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

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

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

    delay(100);

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

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

    x = 0;
    previous = millis();

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

    return answer;
}

Command summary

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

Go to IndexStep 8: Using the shield in standalone mode - HTTP

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

Show Code
/*
 *  Description: This example shows how to do a GET action to a url.
 *  This example shows the AT commands (and the answers of the module) used
 *  to work with HTTP. 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 
 */


int8_t answer;
int onModulePin= 2;

char data[512];
int data_size;

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


void setup(){

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

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

    delay(3000);

    // sets the PIN code
    sendATcommand("AT+CPIN=****", "OK", 2000);

    delay(3000);

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


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

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


}
void loop(){
    // Initializes HTTP service
    answer = sendATcommand("AT+HTTPINIT", "OK", 10000);
    if (answer == 1)
    {
        // Sets CID parameter
        answer = sendATcommand("AT+HTTPPARA=\"CID\",1", "OK", 5000);
        if (answer == 1)
        {
            // Sets url 
            answer = sendATcommand("AT+HTTPPARA=\"URL\",\"www.url.com\"", "OK", 5000);
            if (answer == 1)
            {
                // Starts GET action
                answer = sendATcommand("AT+HTTPACTION=0", "+HTTPACTION:0,200", 10000);
                
                if (answer == 1)
                {
                    x=0;
                    do{
                        sprintf(aux_str, "AT+HTTPREAD=%d,100", x);
                        if (sendATcommand2(aux_str, "+HTTPREAD:", "ERROR", 30000) == 1)
                        {
                            data_size = 0;
                            while(Serial.available()==0);
                            aux = Serial.read();
                            do{
                                data_size *= 10;
                                data_size += (aux-0x30);
                                while(Serial.available()==0);
                                aux = Serial.read();        
                            }while(aux != 0x0D);

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

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

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

    delay(5000);

}

void power_on(){

    uint8_t answer=0;

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

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

}


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

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

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

    delay(100);

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

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


        x = 0;
    previous = millis();

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

    return answer;
}



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

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

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

    delay(100);

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

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


        x = 0;
    previous = millis();

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

    return answer;
}

Command summary

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

Go to IndexFritzing Libraries



modules_fritzing

GPRS/GSM Quadband Module for Arduino (SIM900)

Downloaddownload

GPRS/GSM Quadband Module for Arduino (SIM900) offers GPRS connection to your Arduino board. It includes the SIM900 communication module from SIMCom.

You can download our Fritzing libraries from this area .

Go to IndexLinks and Documentation

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

GPRS/GSM Shield v1.0 SIM900

GPRS Shield MCS01101S

Contents

 [hide

Introduction

The GPRS/GSM Shield provides you a way to use the GSM cell phone network to receive data from a remote location. The shield allows you to achieve this via any of the three methods:

  • Short Message Service
  • Audio
  • GPRS Service

The GPRS/GSM Shield is compatible with all boards which have the same form factor (and pinout) as a standard Arduino Board. The GPRS/GSM Shield is configured and controlled via its UART using simple AT commands. Based on the SIM900 module from SIMCOM, it is like a cell phone. Besides the communications features, the GPRS/GSM Shield has 6 GPIOs, 2 PWMs and an ADC.

Model: MCS01101S
GPRS shield v1.0.jpg

Features

  • Quad-Band 850 / 900/ 1800 / 1900 MHz - would work on GSM networks in all countries across the world.
  • GPRS multi-slot class 10/8
  • GPRS mobile station class B
  • Compliant to GSM phase 2/2+
    • Class 4 (2 W @ 850 / 900 MHz)
    • Class 1 (1 W @ 1800 / 1900MHz)
  • Control via AT commands - Standard Commands: GSM 07.07 & 07.05 | Enhanced Commands: SIMCOM AT Commands.
  • Short Message Service - so that you can send and receive small amounts of data over the network (ASCII or raw hexadecimal).
  • Embedded TCP/UDP stack - allows you to upload data to a web server.
  • RTC supported.
  • Selectable serial port.
  • 2 in 1 headsetjack
  • Low power consumption - 1.5mA(sleep mode)
  • Industrial Temperature Range - -40°C to +85 °C

Application Ideas

  • M2M (Machine 2 Machine) Applicatoions - To transfer control data using SMS or GPRS between two machines located at two different factories.
  • Remote control of appliances - Send SMS while you are at your office to turn on or off your washing machine at home.
  • Remote Weather station or a Wireless Sensor Network - Mate it with [Crowduino v1.0|Crowduino v1.0] and create a sensor node capable of transferring sensor data (like from a weather station - temperature, humidity etc.) to a web server (like pachube.com).
  • Vehicle Tracking System - Couple the GPRS Shield with an Arduino and GPS module and install it in your car and publish your location live on the internet. Can be used as a automotive burglar alarm.

 

Cautions

 

  • Make sure your SIM card is unlocked.
  • The product is provided as is without an insulating enclosure. Please observe ESD precautions specially in dry (low humidity) weather.
  • The factory default setting for the GPRS Shield UART is 19200 bps 8-N-1. (Can be changed using AT commands).

 

Specifications

For SIM900's Specifications, please refer this PDF file: SIM900_SPEC.pdf

ItemMinTypicalMaxUnit
Voltage 4.8 5.0 5.2 VDC
Current / 50 450 mA
Dimension(with antenna) 110x58x19 mm
Net Weight 47±2 g

Interface Function

GPRS Shield interface.png 
Power select - select the power supply for GPRS shield(external power or 5v of arduino)
Power jack - connected to external 4.8~5VDC power supply
Antenna interface - connected to external antenna
Serial port select - select either software serial port or hareware serial port to be connected to GPRS Shield
Hardware Serial - D0/D1 of Arduino/Crowduino/Seeeduino
Software serial - D7/D8 of Arduino/Crowduino/Seeeduino only
Status LED - tell whether the power of SIM900 is on
Net light - tell the status about SIM900 linking to the net
UART of SIM900 - UART pins breakout of SIM900
Microphone - to answer the phone call
Speaker - to answer the phone call
GPIO,PWM and ADC of SIM900 - GPIO,PWM and ADC pins breakout of SIM900
Power key - power up and down for SIM900

Pins usage on Arduino

D0 - Unused if you select hardware serial port to communicate with GPRS Shield
D1 - Unused if you select hardware serial port to communicate with GPRS Shield
D2 - Unused
D3 - Unused
D4 - Unused
D5 - Unused
D6 - Unused
D7 - Used if you select software serial port to communicate with GPRS Shield
D8 - Used if you select software serial port to communicate with GPRS Shield
D9 - Used for software control the power up or down of the SIM900
D10 - Unused
D11 - Unused
D12 - Unused
D13 - Unused
D14(A0) - Unused
D15(A1) - Unused
D16(A2) - Unused
D17(A3) - Unused
D18(A4) - Unused
D19(A5) - Unused

Light Status

LEDStatusFunction
Power-on indicator(Green) Off Power of GPRS Shield is off
  On Power of GPRS Shield is on
Status Indicator(Red) Off Power off
  On Power on
Net indicator(Green) Off SIM900 is not working
  64ms On/800ms Off SIM900 does not find the network
  64ms On/3000ms Off SIM900 finds the network
  64ms On/300ms Off GPRS communication

Usage

Hardware installation

  • Insert an unlocked SIM card to SIM Card Holder - 6 Pin Holder for SIM Cards. Both 1.8 volts and 3.0 volts SIM Cards are supported by SIM900 - the SIM card voltage type is automatically detected.

Inserting the SIM Card into the holder1.jpg Inserting the SIM Card into the holder2.jpg

 

  • Make sure the antenna pad buckled properly - A miniature coaxial RF connector is present on the GPRS Shield board to connect with a GSM Antenna. The connector present on the GPRS Shield is called a U.FL connecto. The GSM Antenna supplied with the GPRS Shield has an SMA connector (and not an RP-SMA connector) on it. A patch cord is also supplied with the GPRS Shield to interface the antenna to the board. The connection topology is shown in the diagram below:
Antenna pad properly buckled

 

  • Assemble the GSM antenna
Assemble the GSM antenna

 

  • Power supply for GPRS shield - Select power source with the switch on board, you can select the 5V power supply from arduino or exteral power.Select the 5V source from Arduino as the following picture:
select 5v of arduino

 

  • Turn on the GPRS shield--There is two ways to turn on the GPRS Shield.

1. Turn on through Hardware. Press the the 'POWERKEY' for few seconds until Power-on indicator(Green) is on.

POWERONkey

2. Turn on through Software. If the JP is soldered,run the following code, the GPRS will POWER on or POWER off.

void power_ON_Down()

pinMode(9, OUTPUT); 
digitalWrite(9,LOW);
delay(1000);
digitalWrite(9,HIGH);
delay(2000);
digitalWrite(9,LOW);
delay(3000);
  • Serial Port(UART) Communication

The GPRS Shield is used UART protocol to communicate with an Arduino/Arduino clone; Users can use jumpers to connect (RX,TX) of the shield to either Software Serial(D8,D7) or Hardware Serial(D1,D0) of the Arduino.Detailed information is showed as the following picture:

Coms.jpg
 
Selectalbe GPRS Shield Communication Port

Note:

  • Users can use "AT+IPR=?" command to see supported baudrate, it will response a list of supported baudrate.
  • Users can use "AT+IPR=x"("x" is value of supported baudrate) to set a fixed baud rate and save the configuration to non-volatile flash memory.
  • When users select Software Serial to communicate, SoftwareSerial Library library should be install in arduino'˜s libraries.

 

  • Plug to Arduino UNO R3 - The GPRS Shield, like any other well designed shield, is stackable as shown in the photo below.
GPRS Shield + Arduino UNO R3

Power Down the GPRS Shield

The GPRS Shield can be turned off by following ways:

  • 1, Normal power down procedure: Turn off the GPRS shield by using Hardware Triger; Press the ON/OFF Button about two seconds.

magic mesh The power down scenarios illustrates as following figure:

ONd.jpg
Figure of Timing of turning off GPRS Shield using Hardware Triger
  • 2, Normal power down procedure: If JP is soldered, then give Digital Pin 9 of the Arduino(act as Software Triger) a Turn off Impulse can turn off the GPRS Shield. The power down scenarios illustrates as following figure:
Pwrd.jpg
Figure of Timing of turning off GPRS Shield using Software Triger

The following code is power down subroutine for Arduino if using software triger:

void powerDown()
{
pinMode(9, OUTPUT); 
digitalWrite(9,LOW);
delay(1000);
digitalWrite(9,HIGH);
delay(2000);
digitalWrite(9,LOW);
delay(3000);
}

 

  • 3, Normal power down procedure: Turn off the GPRS shield by sending AT command "AT+CPOWD=1" to SIM900 module.

When GPRS Shield power dowm in Normal power down procedure, the procedure lets the SIM900 log off from the network and allows the software to enter into a secure state and save data before completely disconnecting the power supply. Before the completion of the power down procedure the SIM900 will send out result code:

NORMAL POWER DOWN

  • 4, Over-voltage or Under-voltage Automatic Power Down: SIM900 will constantly monitor the voltage applied on the VBAT.

①If the voltage ≤ 3.3V, the following URC will be presented:

UNDER-VOLTAGE WARNNING

②If the voltage ≥ 4.7V, the following URC will be presented:

OVER-VOLTAGE WARNNING

③The uncritical voltage range is 3.2V to 4.8V. If the voltage > 4.8V or < 3.2V, SIM900 will be automatic power down soon. If the voltage < 3.2V, the following URC will be presented:

UNDER-VOLTAGE POWER DOWN

④If the voltage > 4.8V, the following URC will be presented:

OVER-VOLTAGE POWER DOWN

  • 5, Over-temperature or Under-temperature Automatic Power Down: SIM900 will constantly monitor the temperature of the module.

①If the temperature > 80℃, the following URC will be presented:

+CMTE:1

②If the temperature < -30℃, the following URC will be presented:

+CMTE:-1

③The uncritical temperature range is -40℃ to +85℃. If the temperature > +85℃ or < -40℃, the module will be automatic power down soon. If the temperature > +85℃, the following URC will be presented:

+CMTE:2

④If the temperature < -40℃, the following URC will be presented:

+CMTE:-2

When the GPRS Shield encounters POWER DOWN scenario, the AT commands can not be executed. The SIM900 logs off from network and enters the POWER DOWN mode, only the RTC is still active. POWER DOWN can also be indicated by STATUS LED(Blue), which is off in this mode.

Note:

  • To monitor the temperature, users can use the “AT+CMTE” command to read the temperature when GPRS Shield is powered on.
  • To monitor the supply voltage, users can use the “AT+CBC” command which includes a parameter: voltage value(in mV) when GPRS Shield is powered on.

 

Upload Sketch to Arduino

Grpsaurduinouart.jpg
Data Stream among Computer, Arduino and GPRS Shield

The following sketch configures Arduino/Arduino clone as serial link between PC and the GPRS Shield(Jumpers on SWserial side). PC would need a serial terminal software to communicate with it - Window's built-in HyperTerminal, Arduino IDE's Serial Monitor, Serial Terminals(sscom32) orBray++ Terminal.

After uploading the sketch to the Arduino board, press the ON/OFF button on the GPRS Shield to turn it on; Now you can see what you get on the serial terminal and the status of the three indicator LEDs, then communicate with your Shield.

//Serial Relay - Arduino will patch a 
//serial link between the computer and the GPRS Shield
//at 19200 bps 8-N-1
//Computer is connected to Hardware UART
//GPRS Shield is connected to the Software UART 

#include <SoftwareSerial.h>

SoftwareSerial GSMSerial(7, 8);

void setup()
{
GSMSerial.begin(19200);               // the GPRS/GSM baud rate   
Serial.begin(19200);                 // the GPRS/GSM baud rate   
}

void loop()
{
if(Serial.available())

GSMSerial.print((char)Serial.read());

else  if(GSMSerial.available())

Serial.print((char)GSMSerial.read());
}

Note:

  • The "AT" or "at" prefix must be set at the beginning of each Command line. To terminate a Command line enter <CR>.

 

Examples

Sending SMS: using Software UART

#include <SoftwareSerial.h>

SoftwareSerial mySerial(7, 8);

void setup()
{
mySerial.begin(19200);  //Default serial port setting for the GPRS modem is 19200bps 8-N-1
mySerial.print("\r");
delay(1000);                    //Wait for a second while the modem sends an "OK"
mySerial.print("AT+CMGF=1\r");    //Because we want to send the SMS in text mode
delay(1000);

//mySerial.print("AT+CSCA=\"+919032055002\"\r");  //Setting for the SMS Message center number,  
//delay(1000);                                  //uncomment only if required and replace with
//the message center number obtained from
//your GSM service provider.
//Note that when specifying a tring of characters
// " is entered as \"

mySerial.print("AT+CMGS=\"+9184460xxxx\"\r");    //Start accepting the text for the message
//to be sent to the number specified.
//Replace this number with the target mobile number.
delay(1000);
mySerial.print("Hello,Elecrow!\r");   //The text for the message
delay(1000);
mySerial.write(0x1A);  //Equivalent to sending Ctrl+Z 
}

void loop()
{
//We just want to send the SMS only once, so there is nothing in this loop.
//If we put the code for SMS here, it will be sent again and again and cost us a lot.
}

Making a call: using Software UART

#include <SoftwareSerial.h>

SoftwareSerial mySerial(7, 8);

void setup()
{
mySerial.begin(19200);               // the GPRS baud rate   
Serial.begin(19200);               // the GPRS baud rate   
delay(2000);
mySerial.println("ATDxxxxxxxxx;"); // xxxxxxxxx is the number you want to dial.  

if(mySerial.available())

Serial.print((unsigned char)mySerial.read());


delay(10000); 
delay(10000); 

mySerial.println("ATH"); //End the call.
if(mySerial.available())

Serial.print((unsigned char)mySerial.read());
}


void loop()
{
//Do nothing
}

Using AT Commands to Control GPIO and PWM pins

Note: GPIOs,PWMs and ADC of the SIM900 module are all 2V8 logic.

#include <SoftwareSerial.h>

SoftwareSerial mySerial(7, 8);

void setup()
{
mySerial.begin(19200);               // the GPRS baud rate   
Serial.begin(19200);               // the GPRS baud rate   
delay(2000);
}

void loop()
{
mySerial.println("AT+SPWM=1,63,100");// set PWM 1 PIN
mySerial.println("AT+SPWM=2,63,50");// set PWM 2 PIN

mySerial.println("AT+SGPIO=0,1,1,1");// set GPIO 1 PIN to 1
mySerial.println("AT+SGPIO=0,12,1,1");
delay(1000);  

mySerial.println("AT+SGPIO=0,1,1,0");// set GPIO 1 PIN to 0
mySerial.println("AT+SGPIO=0,12,1,0");
delay(1000);    
}

A Simple Source Code Example

The demo code below is for the Xduino to send SMS message/dial a voice call/submit a http request to a website and upload datas to the pachube. It has been tested on Arduino Duemilanove but will work on any compatible variant, plesse note that this sketch uses the sorfware UART of ATmega328P. please follow the following steps for running this sketch.

  1. With the GPRS Shield removed, download this sketch into your Arduino.
  2. Disconnect the Xduino from USB port to remove power source.
  3. Set the Serial Port jumpers on the GPRS Shield in SWserial position, to use the Soft Serial port of Arduino.
  4. Connect the antenna to the GPRS Shield and insert the SIM Card.
  5. Mount the GPRS Shield on Arduino.
  6. Connect the Arduino to the computer by USB, and fire up your favorite serial terminal software on computer, choose the COM port for Arduino, set it to operate at 19200 8-N-1.
  7. Type command in the terminal to execute different function, threr are 4 functions in the demo:
    1. If you input 't', the demo will send a SMS message to another cellphone which you set(you need set the number in the code);
    2. If you input 'd', the program will dial a call to the other cellphone that you set(it is also need you set in the code );
    3. If you input 'h', it will submit a http request to a web that you want to access(it need you set the web adress in the code), it will return a string from the website if it goes correctly;
    4. If you input 's', it will upload the datas to the pachube(for detail you can refer to the explanation in the code). I strongly recommend you input 'h' before input 's', because uploading datas to the pachube need do some setting, after execute the function of submit a http request, the setting will be set.
  8. If the program returns error in the terminal after you typed the command, don't worry, just try input the command again.

 

/*Note: this code is a demo for how to using gprs shield to send sms message, dial a voice call and 
send a http request to the website, upload data to pachube.com by TCP connection,

The microcontrollers Digital Pin 7 and hence allow unhindered
communication with GPRS Shield using SoftSerial Library. 
IDE: Arduino 1.0 or later
Replace the following items in the code:
1.Phone number, don't forget add the country code
2.Replace the Access Point Name
3. Replace the Pachube API Key with your personal ones assigned
to your account at cosm.com
*/


#include <SoftwareSerial.h>
#include <String.h>

SoftwareSerial mySerial(7, 8);

void setup()
{
mySerial.begin(19200);               // the GPRS baud rate   
Serial.begin(19200);    // the GPRS baud rate 
delay(500);
}

void loop()
{
//after start up the program, you can using terminal to connect the serial of gprs shield,
//if you input 't' in the terminal, the program will execute  GetSignalQuality(),it will show the signal quality,
//if you input 't' in the terminal, the program will execute SendTextMessage(), it will show how to send a sms message,
//if input 'd' in the terminal, it will execute DialVoiceCall(), etc.

if (Serial.available())
switch(Serial.read())

case 'q':
GetSignalQuality();
break;
case 't':
SendTextMessage();
break;
case 'd':
DialVoiceCall();
break;
case 'h':
SubmitHttpRequest();
break;
case 's':
Send2Pachube();
break;

if (mySerial.available())
Serial.write(mySerial.read());
}
///GetSignalQuality()
///get the signal quality of GSM model.
void GetSignalQuality()
{
mySerial.println("AT+CSQ");  //get the signal Quality
delay(100);
int k=0;
while(mySerial.available()!=0)

SigQ[k]=mySerial.read();  
Serial.write(SigQ[k]);
k+=1;
}


///SendTextMessage()
///this function is to send a sms message
void SendTextMessage()
{
mySerial.print("AT+CMGF=1\r");    //Because we want to send the SMS in text mode
delay(100);
mySerial.println("AT + CMGS = \"+86138xxxxx615\"");//send sms message, be careful need to add a country code before the cellphone number
delay(100);
mySerial.println("A test message!");//the content of the message
delay(100);
mySerial.println((char)26);//the ASCII code of the ctrl+z is 26
delay(100);
mySerial.println();
}

///DialVoiceCall
///this function is to dial a voice call
void DialVoiceCall()
{
mySerial.println("ATD + +86138xxxxx615;");//dial the number
delay(100);
mySerial.println();
}

///SubmitHttpRequest()
///this function is submit a http request
///attention:the time of delay is very important, it must be set enough 
void SubmitHttpRequest()
{
mySerial.println("AT+CSQ");
delay(100);

ShowSerialData();// this code is to show the data from gprs shield, in order to easily see the process of how the gprs shield submit a http request, and the following is for this purpose too.

mySerial.println("AT+CGATT?");
delay(100);

ShowSerialData();

mySerial.println("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"");//setting the SAPBR, the connection type is using gprs
delay(1000);

ShowSerialData();

mySerial.println("AT+SAPBR=3,1,\"APN\",\"CMNET\"");//setting the APN, the second need you fill in your local apn server
delay(4000);

ShowSerialData();

mySerial.println("AT+SAPBR=1,1");//setting the SAPBR, for detail you can refer to the AT command mamual
delay(2000);

ShowSerialData();

mySerial.println("AT+HTTPINIT"); //init the HTTP request

delay(2000); 
ShowSerialData();

mySerial.println("AT+HTTPPARA=\"URL\",\"www.google.com.hk\"");// setting the httppara, the second parameter is the website you want to access
delay(1000);

ShowSerialData();

mySerial.println("AT+HTTPACTION=0");//submit the request 
delay(10000);//the delay is very important, the delay time is base on the return from the website, if the return datas are very large, the time required longer.
//while(!mySerial.available());

ShowSerialData();

mySerial.println("AT+HTTPREAD");// read the data from the website you access
delay(300);

ShowSerialData();

mySerial.println("");
delay(100);
}

///send2Pachube()///
///this function is to send the sensor data to the pachube, you can see the new value in the pachube after execute this function///
void Send2Pachube()
{
mySerial.println("AT+CGATT?");
delay(100);

ShowSerialData();

mySerial.println("AT+CSTT=\"CMNET\"");//start task and setting the APN,
delay(1000);

ShowSerialData();

mySerial.println("AT+CIICR");//bring up wireless connection
delay(300);

ShowSerialData();

mySerial.println("AT+CIFSR");//get local IP adress
delay(2000);

ShowSerialData();

mySerial.println("AT+CIPSPRT=0");
delay(3000);

ShowSerialData();

mySerial.println("AT+CIPSTART=\"tcp\",\"api.cosm.com\",\"8081\"");//start up the connection
delay(2000);

ShowSerialData();

mySerial.println("AT+CIPSEND");//begin send data to remote server
delay(4000);
ShowSerialData();
String humidity = "1031";//these 4 line code are imitate the real sensor data, because the demo did't add other sensor, so using 4 string variable to replace.
String moisture = "1242";//you can replace these four variable to the real sensor data in your project
String temperature = "30";//
String barometer = "60.56";//
mySerial.print("\"method\": \"put\",\"resource\": \"/feeds/43634/\",\"params\"");//here is the feed you apply from pachube
delay(500);
ShowSerialData();
mySerial.print(": ,\"headers\": \"X-PachubeApiKey\":");//in here, you should replace your pachubeapikey
delay(500);
ShowSerialData();
mySerial.print(" \"_cXwr5LE8qW4a296O-cDwOUvfddFer5pGmaRigPsiO0");//pachubeapikey
delay(500);
ShowSerialData();
mySerial.print("jEB9OjK-W6vej56j9ItaSlIac-hgbQjxExuveD95yc8BttXc");//pachubeapikey
delay(500);
ShowSerialData();
mySerial.print("Z7_seZqLVjeCOmNbEXUva45t6FL8AxOcuNSsQS\",\"body\":");
delay(500);
ShowSerialData();
mySerial.print(" \"version\": \"1.0.0\",\"datastreams\": ");
delay(500);
ShowSerialData();
mySerial.println("[\"id\": \"01\",\"current_value\": \"" + barometer + "\",");
delay(500);
ShowSerialData();
mySerial.println("\"id\": \"02\",\"current_value\": \"" + humidity + "\",");
delay(500);
ShowSerialData();
mySerial.println("\"id\": \"03\",\"current_value\": \"" + moisture + "\",");
delay(500);
ShowSerialData();
mySerial.println("\"id\": \"04\",\"current_value\": \"" + temperature + "\"],\"token\": \"lee\"");


delay(500);
ShowSerialData();

mySerial.println((char)26);//sending
delay(5000);//waitting for reply, important! the time is base on the condition of internet 
mySerial.println();

ShowSerialData();

mySerial.println("AT+CIPCLOSE");//close the connection
delay(100);
ShowSerialData();

}
void ShowSerialData()
{
while(mySerial.available()!=0)
Serial.write(mySerial.read());
}

 

 

Using Sms to Control an LED Status

This example is controbuted by MChobby, for more information please visit: http://mchobby.be/wiki/index.php?title=SmsCommand

Send a SMS message "on" or "off" from your cellphone to the GPRS Shield to control the Digital Pin 13(LED) Status.

  • The default Buffer of Rx in SoftwareSerial.h is 32/64, you may experience some data lose while the returns of SIM900 are many(Receiving SMS/TCPIP), you can try to change the Buffer of Rx in SoftwareSerial.h into

#define _SS_MAX_RX_BUFF 128 // RX buffer size

 

 

#include <SoftwareSerial.h>
 
SoftwareSerial mySerial(7, 8);
 
// EN: String buffer for the GPRS shield message

String msg = String("");
// EN: Set to 1 when the next GPRS shield message will contains the SMS message

int SmsContentFlag = 0;
 
// EN: Pin of the LED to turn ON and OFF depending on the received message

int ledPin = 13;
 
// EN: Code PIN of the SIM card (if applied)

//String SIM_PIN_CODE = String( "XXXX" );
 
void setup()
{
  mySerial.begin(19200);               // the GPRS baud rate   
  Serial.begin(19200);                 // the GPRS baud rate
 
  // Initialize la PIN
  pinMode( ledPin, OUTPUT ); 
  digitalWrite( ledPin, LOW ); 
}
 
void loop()
{
    char SerialInByte;
 
    if(Serial.available())
    {
       mySerial.print((unsigned char)Serial.read());
     }  
    else  if(mySerial.available())
    {
        char SerialInByte;
        SerialInByte = (unsigned char)mySerial.read();
 
        // EN: Relay to Arduino IDE Monitor
   
        Serial.print( SerialInByte );
 
        // -------------------------------------------------------------------
        // EN: Program also listen to the GPRS shield message.
   
        // -------------------------------------------------------------------
 
        // EN: If the message ends with <CR> then process the message
       
        if( SerialInByte == 13 ){
          // EN: Store the char into the message buffer
        
          ProcessGprsMsg();
         }
         if( SerialInByte == 10 ){
            // EN: Skip Line feed

         }
         else {
           // EN: store the current character in the message string buffer
 
           msg += String(SerialInByte);
         }
     }   
}
 
// EN: Make action based on the content of the SMS. 
//     Notice than SMS content is the result of the processing of several GPRS shield messages.

void ProcessSms( String sms ){
  Serial.print( "ProcessSms for [" );
  Serial.print( sms );
  Serial.println( "]" );
 
  if( sms.indexOf("on") >= 0 ){
    digitalWrite( ledPin, HIGH );
    Serial.println( "LED IS ON" );
    return;
  }
  if( sms.indexOf("off") >= 0 ){
    digitalWrite( ledPin, LOW );
    Serial.println( "LED IS OFF" );
    return;
  }
}
 
// EN: Send the SIM PIN Code to the GPRS shield

//void GprsSendPinCode(){
//  if( SIM_PIN_CODE.indexOf("XXXX")>=0 ){
//    Serial.println( "*** OUPS! you did not have provided a PIN CODE for your SIM CARD. ***" );
//    Serial.println( "*** Please, define the SIM_PIN_CODE variable . ***" );
//    return;
// }
//  mySerial.print("AT+CPIN=");
// mySerial.println( SIM_PIN_CODE );
}
 
// EN: Request Text Mode for SMS messaging

void GprsTextModeSMS(){
  mySerial.println( "AT+CMGF=1" );
}
 
void GprsReadSmsStore( String SmsStorePos ){
  // Serial.print( "GprsReadSmsStore for storePos " );
  // Serial.println( SmsStorePos ); 
  mySerial.print( "AT+CMGR=" );
  mySerial.println( SmsStorePos );
}
 
// EN: Clear the GPRS shield message buffer

void ClearGprsMsg(){
  msg = "";
}
 
// EN: interpret the GPRS shield message and act appropiately

void ProcessGprsMsg() {
  Serial.println("");
  Serial.print( "GPRS Message: [" );
  Serial.print( msg );
  Serial.println( "]" );
 
//  if( msg.indexOf( "+CPIN: SIM PIN" ) >= 0 ){
//     Serial.println( "*** NEED FOR SIM PIN CODE ***" );
 //    Serial.println( "PIN CODE *** WILL BE SEND NOW" );
 //    GprsSendPinCode();
//  }
 
  if( msg.indexOf( "Call Ready" ) >= 0 ){
     Serial.println( "*** GPRS Shield registered on Mobile Network ***" );
     GprsTextModeSMS();
  }
 
  // EN: unsolicited message received when getting a SMS message
  // FR: Message non sollicité quand un SMS arrive
  if( msg.indexOf( "+CMTI" ) >= 0 ){
     Serial.println( "*** SMS Received ***" );
     // EN: Look for the coma in the full message (+CMTI: "SM",6)
     //     In the sample, the SMS is stored at position 6
     int iPos = msg.indexOf( "," );
     String SmsStorePos = msg.substring( iPos+1 );
     Serial.print( "SMS stored at " );
     Serial.println( SmsStorePos );
 
     // EN: Ask to read the SMS store
     GprsReadSmsStore( SmsStorePos );
  }
 
  // EN: SMS store readed through UART (result of GprsReadSmsStore request)  
  if( msg.indexOf( "+CMGR:" ) >= 0 ){
    // EN: Next message will contains the BODY of SMS
    SmsContentFlag = 1;
    // EN: Following lines are essentiel to not clear the flag!
    ClearGprsMsg();
    return;
  }
 
  // EN: +CMGR message just before indicate that the following GRPS Shield message 
  //     (this message) will contains the SMS body

  if( SmsContentFlag == 1 ){
    Serial.println( "*** SMS MESSAGE CONTENT ***" );
    Serial.println( msg );
    Serial.println( "*** END OF SMS MESSAGE ***" );
    ProcessSms( msg );
  }
 
  ClearGprsMsg();
  // EN: Always clear the flag

  SmsContentFlag = 0; 
}