How to use GPS functions with GSM/GPRS & GPS shield

By on August 13, 2013
Pin It

gsm-shield-SIM908_s

Once again we have prepared some examples related to the GSM/GPRS & GPS shield. In previous posts we have seen how to handle SMS, make calls and use the GPRS connection to send email  or download data from Internet pages.

The shield has been developed to accommodate both forms of SIMComs: SIM900 and SIM908: the latter is characterized by the internal 42 channels GPS receiver, manageable with AT commands.

What’s still to be addressed then is library functions developed for the management of the GPS.

 

Note that SIM908 module also offers the ability to manage lithium-ion battery: can recharge them when connected to an external power supply.

 

In this series of examples you’ll see how to handle the additional functionality provided by the SIM908 relating to geolocation. Obviously, for those who use SIM900 these examples will not work.

 GSM shield_bell2

EXAMPLE 1

As a first sketch, we’ll analyze the one called GSM_GPRSLibrary_GPS that you can find in the example folder of the library.  Let’s start with this to become familiar with the basic functions and then better understand the functioning of the subsequent examples.

Remember that the correct GPS operation you need to make a bridge over the J1 jumper on the module containing the SIM908, which is mounted on the shield.

FT971_3_SIM908

Besides the bridge, which is essential to bring power to the antenna, you must connect the latter and place it on the outside, otherwise be detrimental to the operation of the GPS.

Note that, when placed inside buildings or confined spaces, the receiver will hardly be able to make the fix.

As always, for every sketch related to this shield, you must include the related library (gps.h in this case) and then instantiate an object. This procedure can be done with the following commands:

#include “gps.h”

GPSGSM gps;

Each function that belongs to that class, to be used, needs to be called in the following way.

ObjectName.MethodName(parameters)

After defining the variables needed for the operation of the program, we see the switching on of the GPS receiver.

gps.attachGPS ()

With this call we ask the module to enable GPS function. The use of GPS (as for smartphones) does increase battery consumption by the module, resulting in smaller battery life. In the case of AC power , the power supply shall supports current peaks of about 2A.

It takes a bit of time for the module to fix the satellites: we see, therefore, a delay that is there to allow the module to do this (the time may be shorter, we recommend you to identify the ideal time depending on your application.)

delay (20000);

The module has two modes of initiation for GPS functions, depending on whether they have been used recently or not. In fact, there is a “Hot Start” mode to make the fix in a shorter time if this has been done recently. This feature is transparent to the user and is handled by the module itself.

At this point, after activating the module, we check the status with the command

gps.getStat (),

which returns a value representing the status of the GPS receiver.

 

Four states are possible (GPS OFF, NOT FIXED, 2D FIXED, 3D FIXED).

Regarding the meaning, you can refer to the descriptive table of the function.

char getStat()

Checks the status of the GPS, the possible outputs

are:

0: GPS not started.

1: Fix not run (can be caused by a poor signal quality).

2: 2D Fix executed.

3: 3D Fix executed.

char stat;

stat=gps.getStat();

if(stat==3)

Serial.println(“FIXED”);

 

Once we secured the status of the GPS in relation to the fix,we can get  the coordinates with the command:

gps.getPar(lon,lat,alt,time,vel);

 

The function will save the coordinates within the strings passed as a parameter.

Obviously if you need to perform operations with the data obtained you will have to convert the string to integer or float with special functions.

Once data is obtained, these can be printed with the classic:

Serial.print (char * string);

#include "SIM900.h"

#include <SoftwareSerial.h>

#include "gps.h"

GPSGSM gps;

char lon[15];

char lat[15];

char alt[15];

char time[20];

char vel[15];

char msg1[5];

char msg2[5];

char stat;

char inSerial[20];

int i=0;

boolean started=false;

void setup()

{

 //Serial connection.

 Serial.begin(9600);

 Serial.println("GSM Shield testing.");

 //Start configuration of shield with baudrate.

 if (gsm.begin(9600)){

   Serial.println("\nstatus=READY");

   gsm.forceON(); //To ensure that SIM908 is not only in charge mode

   started=true;

 }

 else Serial.println("\nstatus=IDLE");

 if(started){

   //GPS attach

   if (gps.attachGPS())

     Serial.println("status=GPSREADY");

   else Serial.println("status=ERROR");

   delay(20000); //Time for fixing

   stat=gps.getStat();

if(stat==1)

Serial.println("NOT FIXED");

else if(stat==0)

Serial.println("GPS OFF");

else if(stat==2)

Serial.println("2D FIXED");

else if(stat==3)

Serial.println("3D FIXED");

delay(5000);

//Get data from GPS

gps.getPar(lon,lat,alt,time,vel);

Serial.println(lon);

Serial.println(lat);

Serial.println(alt);

Serial.println(time);

Serial.println(vel);

 }

};

void loop()

{

};

GSM_GPRS_GPS_shield_SIM908

EXAMPLE 2

The second example regards the interpretation and formatting of the location data provided by SIM908.

The problem with GPS data is that, although the location data is unique, there are several formats to describe it.

It can thus arise the problem of finding ourselves using different formats with the risk to be confused. For this reason it is critical to analyze the format used by SIM908 and how you can convert it to other formats, which are also widely used (such as the one used by Google).

 

SIM908 uses a format that is described by the initials ddmm.mmmm, while other devices and services (such as Google Maps) use the decimal dd.dddddd.

 

The decimal format is widely used, it’s easir to manage, in the calculation of distances and speeds.

It is therefore necessary to know the relationship between the two formats in order to to use the one you prefer, based on your need.

The relationship between these two formats is expressed by the following formula:

dd.dddddd = dd + mm.mmmm / 60

Remember that the library provides the coordinates as a string, you need to use a method to convert these coordinates in numerical format if you want to use it within a formula.

One of these functions is contained within the stdlib.h library, can be included with the following command:

# include < stdlib.h>

Within the library you can see the function

atof (const char * str)

that returns a float containing the value expressed by the string.

 

To better understand what is expressed in this section let’s analyze the example.

The example proposed shows how to convert the format of the SIM908 ddmm.mmmm into the widely used dd.dddd format.

Firstly, to differentiate it from the previous example, we have chosen to perform the geolocation only after the user’s request it through a specific command via the serial communication.

Specifically, when the user wants to know his position, expressed in dd.dddd coordinates, he will send the string “GPS” through serial communication.

 

The shield will respond with two values ​,  latitude and longitude, in the Google compatible format (simply insert these data into the search bar of Google Maps to display the location on the map.)

For the interpretation of the messages sent via the serial port, at each iteration of the loop we save all the characters on that port within a char array.

Then using the command

strcmp(inSerial, “GPS”)

you will go checking if the array actually contains the predetermined “GPS” command.

In case yes, you can enter the portion of the code that executes on that command.

 

After the commands to request the longitude and latitude in the native SIM908 -which we already analyzed in the previous example – we find the convert function, used to convert the coordinates.

This function has been developed on purpose and is available at the end of the code.

This function divides the string into the two parts: dd and mm.mmm.

The first problem you encounter concerns the part relative to degrees (the first part), described by the dd: this is not always composed of two characters! If the number is between 0 and 9, this part will be represented with a single character, and the output will be dmm.mmmm instead ddmm.mmmm.

To discriminate these two situations we check for the dot within the string, checking if this is present in position 3 or 4 (remember that in the array positions starts at 0).

This can be done with the function – again, developed on purpose and available at the end of the code –

int strpos (char *str, char *target )

that returns an integer representing the position in which the *target character  is found in the string *str.

Once obtained this information we can extract the one or two characters for the first part of the string.

Similarly we extract the second part related to mm.mmm information, converting it into a floating point number to perform the final calculation described by the formula that we previously seen.

The output will then be composed of two coordinates, latitude and longitude, expressed according to the desired format.

#include “SIM900.h”

#include <SoftwareSerial.h>

#include <stdlib.h>

#include "gps.h"

GPSGSM gps;

char lon[15];

float lon_db;

char lat[15];

float lat_db;

char alt[15];

char time[20];

char vel[15];

char msg1[5];

char msg2[5];

char stat;

char inSerial[20];

int i=0;

boolean started=false;

void setup()

{

 //Serial connection.

 Serial.begin(9600);

 Serial.println("GSM Shield testing.");

 //Start configuration of shield with baudrate.

 if (gsm.begin(2400)){

   Serial.println("\nstatus=READY");

   gsm.forceON(); //To ensure that SIM908 is not only in charge mode

   started=true;

 }

 else Serial.println("\nstatus=IDLE");

 if(started){

   //GPS attach

   if (gps.attachGPS())

     Serial.println("status=GPSREADY");

   else Serial.println("status=ERROR");

 }

 delay(20000); //Time for fixing

};

void loop()

{

 //Read for new byte on serial hardware,

 //and write them on NewSoftSerial.

 serialhwread();

 //Read for new byte on NewSoftSerial.

 serialswread();

};

void serialhwread(){

 i=0;

 if (Serial.available() > 0){

   while (Serial.available() > 0) {

     inSerial[i]=(Serial.read());

     delay(10);

     i++;

   }

   inSerial[i]='\0';

   if(!strcmp(inSerial,"/END")){

     Serial.println("_");

     inSerial[0]=0x1a;

     inSerial[1]='\0';

     gsm.SimpleWriteln(inSerial);

   }

   //Send a saved AT command using serial port.

   if(!strcmp(inSerial,"GPS")){

       stat=gps.getStat();

if(stat==1)

Serial.println("NOT FIXED");

else if(stat==0)

Serial.println("GPS OFF");

else if(stat==2)

Serial.println("2D FIXED");

else if(stat==3)

Serial.println("3D FIXED");

delay(5000);

//Get data from GPS

gps.getPar(lon,lat,alt,time,vel);

       lon_db=convert(lon);

       lat_db=convert(lat);

       Serial.println("dd.dddddd data:");

       Serial.print("LON: ");

       Serial.println(lon_db,4);

       Serial.print("LAT: ");

       Serial.println(lat_db,4);

   }

   //Read last message saved.

   if(!strcmp(inSerial,"MSG")){

     Serial.println(msg1);

   }

   else{

     Serial.println(inSerial);

     gsm.SimpleWriteln(inSerial);

   }

   inSerial[0]='\0';

 }

}

void serialswread(){

 gsm.SimpleRead();

}

int strpos(char *str, char *target) {

 char *res=0;

 res = strstr(str, target);

 if (res == NULL) return false;

 else             return res - str;

}

float convert(char* str){

 float mmmmmm;

 float dd;

 int pos;

 pos=strpos(str,".");

 char dd_str[pos-1];

 dd_str[0]='\0';

 char mmmmmm_str[6];

 mmmmmm_str[0]='\0';

 for (int i=0; i<pos-2; i++){

   dd_str[i]=str[i];

 }

 dd_str[pos-2]='\0';

 dd=atof(dd_str);

 mmmmmm_str[0]=str[pos-2];

 mmmmmm_str[1]=str[pos-1];

 mmmmmm_str[2]=str[pos];

 mmmmmm_str[3]=str[pos+1];

 mmmmmm_str[4]=str[pos+2];

 mmmmmm_str[5]=str[pos+3];

 mmmmmm_str[6]='\0';

 mmmmmm=atof(mmmmmm_str);

 float result;

 result=dd+mmmmmm/1000/60;

 return result;

}

GSM_GPRS_GPS_shield_mounting

EXAMPLE 3

The third example will show you how, with just a few lines of code, it is possible to achieve a locator with a basic function: it sends the position following a call by a given, authorized, number.

 

In this way, if you want to locate the device you’ll just need to call it! After saving the caller’s number on the address book (to get authorization), the shield will reply with an SMS containing latitude and longitude, after refusing the call.

In order not to overcomplicate the program sketch we will not be doing any conversion of the format of the coordinates.

Please pay attention to the first part of the sketch, where the objects related to classes are instantiated.

For the realization of this example, you must use all the classes related to calls, SMS and GPS.

It will therefore be necessary to include all three files for the three classes and instantiate objects for the calling functions.

#include “sms.h”

#include “call.h”

#include “gps.h”

CallGSM call;

SMSGSM sms;

GPSGSM gps;

The sketch periodically checks the status of the calls and, once the incoming call by an authorized number, id identified it executes the routine associated with the sending of location via SMS.

Compared to the examples shown previously , we do not find anything more special, if not the use of the function strcat (char *str1, char *str2) to concatenate two strings.

For the composition of message to send different strings are concatenated to form the text to be sent:

message[0]=’\0′;

 strcat(message,”lon: “);

 strcat(message,lon);

 strcat(message,” lat: “);

 strcat(message,lat);

 

Notice how every time you need to reset the string by putting the terminator ‘\0’ as the first character of the array.

Regarding further details relating to the management of incoming calls and sending messages, you should check these posts, where these topics were explained.

#include "SIM900.h"

#include <SoftwareSerial.h>

#include "sms.h"

#include "call.h"

#include "gps.h"

CallGSM call;

SMSGSM sms;

GPSGSM gps;

char message[40];

char number[15];

byte state;

char lon[15];

float lon_db;

float lon_db_2;

char lat[15];

float lat_db;

float lat_db_2;

char alt[15];

char time[20];

char vel[15];

char msg1[5];

char msg2[5];

char stat;

char inSerial[20];

int i=0;

boolean started=false;

void setup()

{

 //Serial connection.

 Serial.begin(9600);

 Serial.println("GSM Shield testing.");

 //Start configuration of shield with baudrate.

 //For http uses is raccomanded to use 4800 or slower.

 if (gsm.begin(2400)){

   Serial.println("\nstatus=READY");

   gsm.forceON(); //To ensure that SIM908 is not only in charge mode

   started=true;

 }

 else Serial.println("\nstatus=IDLE");

 if(started){

   //GPS attach

   if (gps.attachGPS())

     Serial.println("status=GPSREADY");

   else Serial.println("status=ERROR");

 }

 delay(20000); //Time for fixing

};

void loop()

{

 state=call.CallStatusWithAuth(number,8,10);

 if(state==CALL_INCOM_VOICE_AUTH)

 {

   Serial.println(value);

   delay(1000);

   call.HangUp();

   value=1;

   Serial.println("Chiamata in corso da numero autorizzato");

   stat=gps.getStat();

   delay(5000);

   gps.getPar(lon,lat,alt,time,vel);

   message[0]='\0';

   strcat(message,"lon: ");

   strcat(message,lon);

   strcat(message," lat: ");

   strcat(message,lat);

   sms.SendSMS(number,message);

 }

 delay(500);

};

About Boris Landoni

Boris Landoni is the technical manager of Open-Electronics.org. Skilled in the GSM field, embraces the Open Source philosophy and its projects are available to the community.

16 Comments

  1. Pingback: How to use GPS functions with GSM/GPRS & GP...

  2. Pingback: What Is The Meaning Of Gprs Class 12 | MeaningFull

Leave a Reply

Your email address will not be published. Required fields are marked *