GSM LIBRARY for ARDUINO

This is a library used to do GSM and GPRS connections using Hayes AT commands, it was developed to be used with a Telit module.

Copyright (c) Justin Downs 12/20/10 All right reserved. 
for more info/tutorials visit:
www.GROUNDLAB.CC
****
This library is free software; you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published by 
the Free Software Foundation; either version 2.1 of the License, or (at 
your option) any later version.
****
This library is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY or LIABILITY; without even the implied warranty of MERCHANTABILITY 
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 
for more details. You should have received a copy of the GNU Lesser General Public 
License along with this library; if not, write to the Free Software Foundation, Inc., 
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or by visiting the Free 
Software Foundation LPGL page at http://www.gnu.org/licenses/lgpl.html 

WHAT IS IT?

This is a code library to help you use a Telit (or other compatible Gsm module) with the Arduino platform. You can import the library into you Arduino sketch and use the functions to send and receive text messages EG. “oh geez, LOL” or make data connections using GPRS which you can use to do HTTP GET's and POST's EG. “http://wiki.groundlab.cc/doku.php?id=gsm_arduino_library”.

How does it work?

The Steps you have to take to use this library are:

1. Get a Gsm module and connect it to your Arduino Programing board.
2. Install the Gsm Library in your Arduino library folder on your computer. 
3. Import the library into your sketch.
4. USE IT!

INSTALLATION AND SET UP

!!!!

READ FIRST

Before setting it up it is helpful to review, if you don't know already the steps in adding a library from Arduino they can be found here: http://www.arduino.cc/en/Hacking/Libraries

extra tip the Arduino preference are stored in the .arduino file of your home directory.You can change your sketchbook paths etc. there.

!!!!

1.Hardware setup

The first step involves connecting the physical hardware of the GSM module to the AVR/Arduino microcontroller you are using. GroundLab currently has two modules which can both be used with the Arduino platform, Found here:.

->GroundLab devices<-

For more information on setting up general GSM/Arduino hardware and the GroundLab boards see here:

1. Hardware Information:

->Connecting Microcontrollers to GSM modules<-

2.Software setup

The second step is getting the code onto your computer and into the libraries folder of the Arduino IDE. To do this you need to have a folder named Gsm with all the downloaded .h and .cpp files of the GroundLabs GSM library in your Arduino environments libraries Directory. To do this follow the below steps.

1. Git the code from GroundLabs GitHub account, located here:

https://github.com/GROUNDLAB/GSM-ARDUINO

2. Download the code as a tar.gz or zip file and save it to a directory on your computer.

3.Then go to the directory and uncompress the file,
 (Below is how to do it from the command line, you can 
 just double click on the file for most OS's and your 
 computer will know how to uncompress the file)

4.Next thing is to rename the newly uncompressed folder to Gsm
  and move it to the proper Arduino folder libraries.
  In my version of Arduino it is located here: 
   -> ~/AVR/Ardunio/arduino-0021/libraries/
  According to the latest documentation jan(2011) it should be in your 
   -> Documents/ directory

You can now see the folder Gsm has all the files and is located in the library folder. It is quicker with the command line but you can also just rename the folder in your finder and drag and drop into the right folder.

5. Now you you should be able to open up the Arduino application and go 
   to the "import libraries tab" and see the Gsm folder. 

3.Import Library

Now all you have to do is import the library and start using the code! To import the code you go to:

Sketch 
   ->import library >Gsm

Examples: The Gsm library also comes with a examples folder in it. Once you put the gsm library in the right place the examples folder should become accessible to you under:

This is a good place to start. So go to the examples folder and open the SMS example.

4.Use it

When you import the Gsm library you get a couple #import statements that provides the functions you can now use in your sketch, to see a complete overview of the library and how to use it go here:

->GSM_LIBRARY<-

SMS example

The SMS example code allows you to send a SMS text message, receive a message or save delete selected messages off the phone. There are three functions that are wrote to display the basic flow you would use to manage messages:

bool readDeleteMessages();       // Used to read any received messages and then deletes them
bool checkNetworkSendMessage();  // Used to check if your on the network and then sends SMS
void talkReply();                // Used to send commands directly to the Telit 

Using this example is a good place to start when testing out the library.

#include <gsmSMS.h> //You just need to import the gsmSMS.h file if you are just doing SMS message
 
//*******PIN DEFS***********
#define turnOnPin 40        //used to turn on off Telit
//**************************
 
//******FUNC DEFS***********
 
bool readDeleteMessages();       // Used to read any received messages and then deletes them
bool checkNetworkSendMessage();  // Used to check if your on the network and then sends SMS
void talkReply();                // Used to send commands directly to the Telit and trigger the above functions
 
//**************************
 
//********make a object of Gsm class********************
/*First you have to make the gsmSMS object, the arguments are in order
*GsmSMS (#1 Name of the serial port connected to GSM (your choice),#2 the address of millis function(just copy whats there) )*/
gsmSMS  myGsmSMS(Serial3,&millis,&Serial);        //gsmSMS TELIT SMS
//******************************************************
 
void setup(){
  Serial.begin(9600);                // used for debugging
  Serial3.begin(9600);               // used for talking to telit 
  Serial.println("hello");           // say hello to check serial line 
 
 /*If you are using a Telit module with a on/off pin you can
 *use the turnOn function. It is used with the supplied circuit
 *from Wiki.Grounglab.cc
 
 //******************************
 //myGsmSMS.turnOn(turnOnPin);  //only needed if you have supporing hardware to turn on the Telit
 //******************************
 
 
 /*Then call the init function which sets the band to use.
 *More info found at:
 *http://en.wikipedia.org/wiki/GSM_frequency_bands
 *
 *0 - GSM 900MHz + DCS 1800MHz (eroupe,africa,some asia/south america)
 *1 - GSM 900MHz + PCS 1900MHz
 *2 - GMS 850MHz + DCS 1800MHz 
 *3 - GMS 850MHz + PCS 1900MHz  (north america,some south america)*/
 
 //******************************
  myGsmSMS.init(3);               // set for New York NY
  Serial.println("done intit");
 //****************************** 
 
}
 
void loop(){
  /*shows a basic example of how to send a text message
  *The first agrument is the number you wish to dial as a const char,
  *the second is the message you want to send also as a const char.
  *So if you wanted to send 1-800-POODLES a message you can say
  *EXAMPLE:*/
 
  //char myNumber[]={"18007663537"};               //The number you want to dial
  //char myMessage[]={"Hello Poodles"};            //The message
  //GsmSMS.sendNoSaveCMGS(myNumber,myMessage);     //Send it
 
  /* OR you can just say */ 
 
  //GsmSMS.sendNoSaveCMGS("18007663537","Hello Poodles");
 
  /*Use the talkReply function to get a good overview of the functionality (see below)*/
 
  talkReply();   
}
 
//type '%' to send a text message ***REPLACE tel# AND MESSAGE FIRST! in checkNetworkSendMessage()***
//type '~' to read any messages that have been sent to your phone and then delete them.
//type '^' to shutdown telit (if your using a telit)
//otherwise when you type you are sending commands striaght to the telit like "AT"
void talkReply(){
 
        //listens for your typing
        if (Serial.available()){
          while (Serial.available()>0){
            char c = Serial.read();
                  switch (c){
                    case '%': checkNetworkSendMessage();
                    break;
                    case '~': readDeleteMessages(); 
                    break;
                    case '^': myGsmSMS.turnOff();
                    break;
                    default:
                    Serial3.write(c);
                    break;
                    }
                  delay(50);    //to signal the end of TX
          }
          Serial3.println();    //send <CR>
        }
        //listen for reply, print it
        if (Serial3.available()>0){
            while (Serial3.available()>0){
                  Serial.write(Serial3.read());               
            }
 
        }
}
 
 
/*Below is an example of checking to see if you 
 *have received messages, if so read them
 *and delete the read messages.*/
 
bool readDeleteMessages(){
   char myMessages[500];                                              //used to hold messages
   if (strcpy(myMessages, myGsmSMS.readAllCMGL("REC UNREAD",500))){   //gets messages, 500 sets max size of message
     Serial.write(myMessages);                                        //display messages
    /*ERASE all read messages*/
    myGsmSMS.deletMessagesCMGD("1,2");
    return 1;
   }
return 0;
}
 
/*A Example of how to send a message, it is a good 
idea to check network before completeing a send.*/
 
bool checkNetworkSendMessage(){
  if (myGsmSMS.checkCREG()){              //Check if your registered with network, Returns true if you are.
      if(myGsmSMS.checkCSQ() > 15){         //Check the signal quality 20 for GPRS, 15 is ok for SMS
        /* If everything is fine go ahaed with the send
        ****Replace tel # and message FIRST!**********/
        if (myGsmSMS.sendNoSaveCMGS("18007663537","Hello Poodles")) return true;        
      }
  }
  return false;
}
 
/*Examples of more functions in the SMS class*/
 
void gsmSMSTester(){
//CHECK CMGD gives a numerical list of all messages which are stored seperated by ','
      Serial.write( myGsmSMS.checkCMGDList() );
//ERASE CMGD (with arg) erases message at id(EG 1,2,3,4) arg
//      GsmSMS.deletMessagesCMGD("2");
//READ CMGR read message with specified ID     
//      GsmSMS.readMessageCMGR("4");
//SAVE CMGW saves a message to memory and CMSS sends saved message.
//      GsmSMS.sendSavedMessageCMSS(GsmSMS.saveMessageCMGW("18007663537","I remember!"));        
//CHECK CPMS gets number of messages or total space availible in sim memory selected by arg.
//      Serial2.write( GsmSMS.getNumMesInMemCPMS(1) );
 
}

GPRS example

The GPRS example code allows you to make a GPRS data connection using the TCP/IP protocol. This allows you to do a HTTP GET or POST on any website. You will need to have a data plan from a cell carrier and their APN, username and password to make a connection. If you don't know what these things are you can brush up on them here:

->GSM GPRS OVERVIEW<-

The main functions are written out to give you an example of the steps you take in opening a connection with the network, obtaining an IP address and dialing a socket to a web server.

1.First step is to contact the network and obtain a IP address, you do this with this function:

//connects to network and gets IP from gatway
bool setNetworkandGetIP(char* APN, char* userName, char* password);

2.Once you have a IP address you can dial a socket and contact a web server with a GET or POST request:

//used to place a HTTP GET Request
bool placeGetRequest(char* hostName, char* resourcePath, uint16_t dataSize);       
//Or
// Used to send a  HTTP POST
bool placePostRequest(char* hostName, char* resourcePath, char* postString, uint16_t dataSize); 

3.Last is to free your IP address when you want to log off from the network:

//used to diconnect from network and free resources
void disconnectGiveBackIP(char* userName, char* password);

The last function lets you send commands directly to the Telit:

// Used to send commands directly to the Telit and trigger 
the above functions *used for testing*
void talkReply();  

The below code shows and example on how to use each of these !!!!Be sure to switch the URls in the examples below!!!!!

#include <gsmGPRS.h>
 
//*******PIN DEFS***********
#define turnOnPin 40        //used to turn on off Telit
//**************************
 
//******FUNC DEFS***********
//connects to network and gets IP from gatway
bool setNetworkandGetIP(char* APN, char* userName, char* password);
//used to place a HTTP GET Request
bool placeGetRequest(char* hostName, char* resourcePath, uint16_t dataSize);       
// Used to send a  HTTP POST
bool placePostRequest(char* hostName, char* resourcePath, char* postString, uint16_t dataSize); 
//used to diconnect from network and free resources
void disconnectGiveBackIP(char* userName, char* password);
// Used to send commands directly to the Telit and trigger the above functions *used for testing*
void talkReply();                
 
//**************************
 
//********make a object of Gsm class********************
/*First you have to make the gsmSMS object, the arguments are in order
*GsmSMS (#1 Name of the serial port connected to GSM (your choice),#2 the address of millis function(just copy whats there) )*/
gsmGPRS  myGsmGPRS(Serial3,&millis,&Serial);        //gsmSMS TELIT SMS
//******************************************************
 
void setup(){
  Serial.begin(9600);                // used for debugging
  Serial3.begin(9600);               // used for talking to telit 
  Serial.println("hello");           // say hello to check serial line 
 
 /*If you are using a Telit module with a on/off pin you can
 *use the turnOn function. It is used with the supplied circuit
 *from Wiki.groundlab.cc
 
 //******************************
 // myGsmGPRS.turnOn(turnOnPin);
 //******************************
 
 /*Then call the init function which sets the band to use.
 *More info found at:
 *http://en.wikipedia.org/wiki/GSM_frequency_bands
 *
 *0 - GSM 900MHz + DCS 1800MHz (eroupe,africa,some asia/south america)
 *1 - GSM 900MHz + PCS 1900MHz
 *2 - GMS 850MHz + DCS 1800MHz 
 *3 - GMS 850MHz + PCS 1900MHz  (north america,some south america)*/
 
 //******************************
  myGsmGPRS.init(3);               // set for New York NY
  Serial.println("done init");
 //****************************** 
 
}
 
bool isConnected = false;
void loop(){
   talkReply();  
}
 
 
//type '%' to send a text message ***REPLACE tel# AND MESSAGE FIRST!***
//type '~' to read any messages that have been sent to your phone and then delete them.
//type '^' to shutdown telit (if your using a telit)
//otherwise when you type you are sending commands straight to the telit like "AT"
void talkReply(){
 
        //listens for your typing
        if (Serial.available()){
          while (Serial.available()>0){
            char c = Serial.read();
                  switch (c){ 
                   case '!':  //get IP adress do this once
                    setNetworkandGetIP("wap.cingular","WAP@CINGULARGPRS.COM", "CINGULAR1");
                    break;
 
                    case '%':  //place a get request
                                    //HOST                      //Resource Path        //received data size
                    placeGetRequest("www.google.com", "/index.html", 500);
                    break;
 
                    case '~':  //place Post request
                                     //HOST                      //resource path    //POST STRING          //received data size
                    placePostRequest("www.someUrl.com","/postTest/myPing.php","testPing=helloworld", 500);
                    break;
 
                    case '^':  //disconnect from network and turn off telit
                    disconnectGiveBackIP("WAP@CINGULARGPRS.COM","CINGULAR1"); //username password for ATT 
                    isConnected = false;                                      //we are not connected             
                    myGsmGPRS.turnOff();
                    break;
 
                    default:
                    Serial3.write(c);
                    break;
                    }
                  delay(50);    //to signal the end of TX
          }
          Serial3.println();    //send <CR>
        }
        //listen for reply, print it
        if (Serial3.available()>0){
            while (Serial3.available()>0){
                  Serial.write(Serial3.read());               
            }
 
        }
}
 
 
// ATT settings        "wap.cingular""WAP@CINGULARGPRS.COM","CINGULAR1"
bool setNetworkandGetIP(char* APN, char* userName, char* password){
//SET NETWORK CONNECTION
//SETS the context number associated with a PDP protocal "IP"/"PPP" and APN number.
        //context "2" now has these settings (NOTE don't use "0" it is reserved for SMS)
        //*********************************
        Serial.write("CGDCONT");
        myGsmGPRS.setApnCGDCONT("2","IP",APN);
        //*********************************
        //SETS the TCP/IP stack
        //after command socket conection ID 1 is now linked to context ID 2 data, with default timeouts TCP/IP
        //*********************************
        Serial.write("SCFG");
        myGsmGPRS.setTcpIpStackSCFG("1","2");
        //*********************************      
        //REGISTERS with the network, receives IP address and network resources.
        //connect the specified context ID ("2") to the network. 
        //1 gets network resources 0 disconnects from network and frees resources.
        //*****************************************************************
        Serial.write("SGACT");
        if(myGsmGPRS.setContextSGACT("2","1",userName,password)) return true;
        //*****************************************************************
 
 return false;  
}
 
//Test off my server, please change "www.johnhenryshammer.com", "/cTest/testGet.html" 500
bool placeGetRequest(char* hostName, char* resourcePath, uint16_t dataSize){
         char myGet[dataSize];                                         //used to hold GET reply
         if( myGsmGPRS.socketDialSD("1","0","80",hostName)){           //dial the socket
              //Constructs and sends a get request on open socket,
              //copy reply into your array.
              strcpy(myGet, myGsmGPRS.getHTTP(dataSize,hostName,resourcePath,"HTTP/1.1",true) );   
 
              //Suspends listing to socket, socket can still 
              //receive data till a SH command is issued to 
              //shut the socket, SEE BELOW
              myGsmGPRS.suspendSocket();
         }else return false;                                            //if we didn't get CONNECT
 
        //OPTIONAL*********
        //AT#SI can be implemented to view the info of a socket
        Serial.write(myGsmGPRS.socketInfoSI("1") );                     //see the bytes transfered
        //*****************
 
        //AT#SH closes the socket connection, no data in or out
        myGsmGPRS.closeSocketSH("1");
 
        Serial.write("GET Request: \n");
        Serial.write(myGet);                                      //display GEt reply 
 
}
 
//"www.johnhenryshammer.com" "/cTest/myPing.php" "testPing=helloworld" 500
bool placePostRequest(char* hostName, char* resourcePath, char* postString, uint16_t dataSize){
          char myPostReply[dataSize];                                       //used to hold Post reply
          if( myGsmGPRS.socketDialSD("1","0","80",hostName)){
                //Johny 5 is the agent if you want to change it
                //copy reply into your array
                strcpy(myPostReply,myGsmGPRS.postHTTP(dataSize,hostName,resourcePath,
                "Johnny 5", "HTTP/1.1",true, postString));
 
                //Suspends listing to socket, socket can still 
                //receive data till a SH command is issued to 
                //shut the socket.
                        myGsmGPRS.suspendSocket();                          
                }else return false;                                         //if we didn't get CONNECT
 
          //OPTIONAL*********
          //AT#SI can be implemented to view the info of a socket
          Serial.write(myGsmGPRS.socketInfoSI("1") );                       //see the bytes transfered
          //*****************
 
          //AT#SH closes the socket connection, no data in or out
          myGsmGPRS.closeSocketSH("1");
 
          Serial.write("POST Reply: \n");
          Serial.write(myPostReply);                                        //display GEt reply       
}
 
//ATT NYC -> "WAP@CINGULARGPRS.COM" "CINGULAR1"
void disconnectGiveBackIP(char* userName, char* password){
        // Disconect and Give back the IP to the network
        myGsmGPRS.setContextSGACT("2","0",userName,password);  
}
Navigation
Print/export
Toolbox