How to use GPS functions with GSM/GPRS & GPS shield
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.
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.
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()
{
};
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]='



