Testing the location functions

Before we dive into the two exciting projects of this chapter, we'll first make a simple test using the FONA shield, and see whether it can actually locate our project on a map. The sketch will actually test whether the GPS location is working correctly.

If not, no worries: the sketch, and the other projects of this chapter, will automatically use GPRS location instead. It's less precise, but works quite well. This will be the case if you are testing this project inside, for example.

This is the complete code for this part:

// Libraries
#include "Adafruit_FONA.h"
#include <SoftwareSerial.h>

// Pins
#define FONA_RX 2
#define FONA_TX 3
#define FONA_RST 4

// Buffer
char replybuffer[255];

// Instances
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
SoftwareSerial *fonaSerial = &fonaSS;
Adafruit_FONA fona = Adafruit_FONA(FONA_RST);

void setup() {
 
  // Init board
  while (!Serial);
  Serial.begin(115200);
  Serial.println(F("FONA location test"));
  Serial.println(F("Initializing....(May take 3 seconds)"));

  fonaSerial->begin(4800);
  if (! fona.begin(*fonaSerial)) {
    Serial.println(F("Couldn't find FONA"));
    while(1);
  }
  Serial.println(F("FONA is OK"));

  // Print SIM card IMEI number.
  char imei[15] = {0}; // MUST use a 16 character buffer for IMEI!
  uint8_t imeiLen = fona.getIMEI(imei);
  if (imeiLen > 0) {
    Serial.print("SIM card IMEI: "); Serial.println(imei);
  }

  // Setup GPRS APN (username/password optional)
  fona.setGPRSNetworkSettings(F("your_APN"));
  //fona.setGPRSNetworkSettings(F("your_APN"), F("your_username"), F("your_password"));

  // Turn GPS on
  if (!fona.enableGPS(true)) {
    Serial.println(F("Failed to turn on GPS"));
  }

  // Turn GPRS on
  fona.enableGPRS(true);

  // Decide between GPS or GPRS localisation
  boolean GPSloc;
  int8_t stat;

  // Check GPS fix
  stat = fona.GPSstatus();
  if (stat < 0) {
    GPSloc = false;
  }
  if (stat == 0 || stat == 1) {
    GPSloc = false;
  }
  if (stat == 2 || stat == 3) {
    GPSloc = false;
  }

  // Print which localisation method is used
  Serial.print("Localisation method: ");
  if (GPSloc) {Serial.println("GPS");}
  else {Serial.println("GPRS");}

  // Print position
  if (GPSloc) {
    char gpsdata[80];
    fona.getGPS(0, gpsdata, 80);
    Serial.println(F("Reply in format: mode, longitude, latitude, altitude, utctime(yyyymmddHHMMSS), ttff, satellites, speed, course"));
    Serial.println(gpsdata); 
  }
  else {
    uint16_t returncode;
    if (!fona.getGSMLoc(&returncode, replybuffer, 250))
      Serial.println(F("Failed!"));
    if (returncode == 0) {
      Serial.println(replybuffer);
    } else {
      Serial.print(F("Fail code #")); Serial.println(returncode);
    }
  }
}

void loop() {
  // Nothing here
}

We are now going to look at the important parts of this sketch.

It starts by importing the required libraries:

#include "Adafruit_FONA.h"
#include <SoftwareSerial.h>

Then, we define the pins that the FONA is connected to:

#define FONA_RX 2
#define FONA_TX 3
#define FONA_RST 4

We create some instances for the SoftwareSerial object and the FONA breakout:

SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
SoftwareSerial *fonaSerial = &fonaSS;
Adafruit_FONA fona = Adafruit_FONA(FONA_RST);

Then, we initialize the FONA:

while (!Serial);
Serial.begin(115200);
Serial.println(F("FONA location test"));
Serial.println(F("Initializing....(May take 3 seconds)"));

fonaSerial->begin(4800);
if (! fona.begin(*fonaSerial)) {
  Serial.println(F("Couldn't find FONA"));
  while(1);
}
Serial.println(F("FONA is OK"));

Following this is where you need to put your GPRS data. This completely depends on your phone carrier. I simply had to put in an APN, which was internet, but you might have to put a username and password as well. Contact your carrier to get the exact information, and then comment/uncomment the required line and fill out the data:

fona.setGPRSNetworkSettings(F("your_APN"));
//fona.setGPRSNetworkSettings(F("your_APN"), F("your_username"), F("your_password"));

Then, we can enable the GPS:

if (!fona.enableGPS(true)) {
  Serial.println(F("Failed to turn on GPS"));
}

We also enable the GPRS connection:

fona.enableGPRS(true);

When this is done, we get the state of the GPS, and check whether we can locate a GPS satellite and get a fix. If yes, we'll use the GPS for location purposes. If not, we'll switch to a GPRS location:

stat = fona.GPSstatus();
if (stat < 0) {
  GPSloc = false;
}
if (stat == 0 || stat == 1) {
  GPSloc = false;
}
if (stat == 2 || stat == 3) {
  GPSloc = false;
}

Once we know which location method to use, we can actually get the location, depending on the chosen method:

if (GPSloc) {
  location = getLocationGPS();
  latitude = getLatitudeGPS(location);
  longitude = getLongitudeGPS(location);
  latitudeNumeric = convertDegMinToDecDeg(latitude.toFloat());
  longitudeNumeric = convertDegMinToDecDeg(longitude.toFloat());
}
else {
  location = getLocationGPRS();
  latitude = getLatitudeGPRS(location);
  longitude = getLongitudeGPRS(location);
  latitudeNumeric = latitude.toFloat();
  longitudeNumeric = longitude.toFloat();
}
Serial.print("Latitude, longitude: ");
Serial.print(latitudeNumeric, 6);
Serial.print(",");
Serial.println(longitudeNumeric, 6);

As you can see, we are calling a few helper functions here to get the latitude and longitude as float variables. We are now going to see all these functions in detail.

Here is the detail of the function to get the location using GPS:

String getLocationGPS() {

  // Buffer
  char gpsdata[80];

  // Get data
  fona.getGPS(0, gpsdata, 80);
  return String(gpsdata);
}

This function is really simple, as it simply gets the data from the GPS of the FONA, and returns it as a String.

The function to get the location using GPRS is similar:

String getLocationGPRS() {

  // Buffer for reply and returncode
  char replybuffer[255];
  uint16_t returncode;

  // Get and return location
  if (!fona.getGSMLoc(&returncode, replybuffer, 250))
    return String("Failed!");
  if (returncode == 0) {
    return String(replybuffer);
  } else {
    return String(returncode);
  }
 
}

Then, we actually need to extract the data from the returned String object, and get the latitude and longitude of our GPS module. Here is the function for the longitude using the GPRS location:

String getLongitudeGPRS(String data) {

  // Find commas
  int commaIndex = data.indexOf(','),
  int secondCommaIndex = data.indexOf(',', commaIndex+1);

  return data.substring(0, commaIndex);
}

This is the function to get the latitude using the GPRS location:

String getLatitudeGPRS(String data) {
 
  // Find commas
  int commaIndex = data.indexOf(','),
  int secondCommaIndex = data.indexOf(',', commaIndex+1);

  return data.substring(commaIndex + 1, secondCommaIndex);
}

For the GPS location, things are similar. However, we need one extra function for the GPS module. Indeed, the latitude and longitude are given in degrees-minutes-seconds, and we need to convert this to a numeric format. This is done using the following function:

double convertDegMinToDecDeg (float degMin) {
  double min = 0.0;
  double decDeg = 0.0;

  // Get the minutes, fmod() requires double
  min = fmod((double)degMin, 100.0);

  //rebuild coordinates in decimal degrees
  degMin = (int) ( degMin / 100 );
  decDeg = degMin + ( min / 60 );

  return decDeg;
}

It's now time to test the sketch! Simply put all the code in the Arduino IDE, update your GPRS settings, and upload it to the board. Then, open the serial monitor and this is what you should see:

Testing the location functions

As you can see, I was testing this while indoors so the sketch used the GPRS location. I then simply copied the latitude and longitude and pasted them into Google Maps:

Testing the location functions

I immediately saw a point close to my own location, which was 100-150 meters off my real location. Not too bad if you need to track whether something is inside or outside a city for example.

I then tried again outside, with nothing between the GPS antenna and the sky. Then, the sketch automatically selected the GPS location option:

Testing the location functions

I then also copied and pasted the GPS latitude and longitude into Google Maps:

Testing the location functions

This time, the location was really accurate and showed exactly where I was at that moment.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.124.21