1

I'm using the Adafruit SIM808 breakout board to text a GPS link to Google Maps when pinged. My program is mostly working, but the GPS data that I get has no "N, S, E, W" indicators. In addition, I know that the longitude where I live is negative but it's coming out as positive. This is the output that I get:

enter image description here

This is the code that triggers that output:

int8_t stat;
// check GPS fix
stat = fona.GPSstatus();
if (stat < 0)  {
  Serial.println(F("Failed to query"));
}
if (stat == 0) {
  Serial.println(F("GPS off"));
}
if (stat == 1) {
  Serial.println(F("No fix"));
}
if (stat == 2) {
  Serial.println(F("2D fix"));
}
if (stat == 3) {
  Serial.println(F("3D fix"));
}

// check for GPS location
char gpsdata[120];
fona.getGPS(0, gpsdata, 120);
Serial.println(gpsdata);

I'm already reading about how to fix the GPS data so that it can be used by Google Maps, but I don't know what to do about the issue of not having the directional information/sign.

Here is the full code, just for reference:

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

#define FONA_RX 2
#define FONA_TX 3
#define FONA_RST 4
#define FONA_KEY 7
#define FONA_PS 8

// this is a large buffer for replies
char replybuffer[255];

SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
SoftwareSerial *fonaSerial = &fonaSS;
Adafruit_FONA fona = Adafruit_FONA(FONA_RST);
uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);

void setup() {
  Serial.begin(115200);
  pinMode(FONA_KEY, OUTPUT);
  pinMode(FONA_PS, INPUT);
  analogReference(INTERNAL);
  delay(2000);

  TurnOffFona();

  Serial.println(F("FONA SMS caller ID test"));
  Serial.println(F("Initializing....(May take 3 seconds)"));
  delay(1000);

  TurnOnFona();

  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);
  }

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

  Serial.println("FONA Ready");
}


char fonaInBuffer[64]; //for notifications from the FONA

void loop() {
  char* bufPtr = fonaInBuffer; //handy buffer pointer

  if (fona.available()) {
    //any data available from the FONA?
    int slot = 0; //this will be the slot number of the SMS
    int charCount = 0;
    //Read the notification into fonaInBuffer
    do  {
      *bufPtr = fona.read();
      Serial.write(*bufPtr);
      delay(1);
    } while ((*bufPtr++ != '\n') && (fona.available()) && (++charCount < (sizeof(fonaInBuffer) - 1)));

    //Add a terminal NULL to the notification string
    *bufPtr = 0;

    //Scan the notification string for an SMS received notification.
    //  If it's an SMS message, we'll get the slot number in 'slot'
    if (1 == sscanf(fonaInBuffer, "+CMTI: \"SM\",%d", &slot)) {
      Serial.print("slot: "); Serial.println(slot);
      char callerIDbuffer[32];  //we'll store the SMS sender number in here

      // Retrieve SMS sender address/phone number.
      if (! fona.getSMSSender(slot, callerIDbuffer, 31)) {
        Serial.println("Didn't find SMS message in slot!");
      }
      Serial.print(F("FROM: ")); Serial.println(callerIDbuffer);

      int8_t stat;
      // check GPS fix
      stat = fona.GPSstatus();
      if (stat < 0)  {
        Serial.println(F("Failed to query"));
      }
      if (stat == 0) {
        Serial.println(F("GPS off"));
      }
      if (stat == 1) {
        Serial.println(F("No fix"));
      }
      if (stat == 2) {
        Serial.println(F("2D fix"));
      }
      if (stat == 3) {
        Serial.println(F("3D fix"));
      }

      // check for GPS location
      char gpsdata[120];
      fona.getGPS(0, gpsdata, 120);
      Serial.println(gpsdata);
      String gpsString;

      gpsString = (String) gpsdata; //re-cast chr array as string.
      Serial.println(gpsString);
      int commaIndex = gpsString.indexOf(',');
      int secondCommaIndex = gpsString.indexOf(',', commaIndex + 1);
      int thirdCommaIndex = gpsString.indexOf(',', secondCommaIndex + 1);
      int fourthCommaIndex = gpsString.indexOf(',', thirdCommaIndex + 1);

      String firstValue = gpsString.substring(0, commaIndex);
      String rawLat = gpsString.substring(commaIndex + 1, secondCommaIndex);
      String rawLon = gpsString.substring(secondCommaIndex + 1, thirdCommaIndex);
      String rawAlt = gpsString.substring(thirdCommaIndex + 1, fourthCommaIndex);

      int decimalIndex = rawLat.indexOf('.');
      String lat1 = rawLat.substring(0, decimalIndex);
      String lat2 = rawLat.substring(decimalIndex + 1, rawLat.length());
      Serial.println(lat1);
      Serial.println(lat2);
      rawLat = lat1.substring(0, 2) + "." + lat1.substring(3, lat1.length()) + lat2;
      Serial.println(rawLat);

      int decimal2Index = rawLon.indexOf('.');
      String lon1 = rawLon.substring(0, decimal2Index);
      String lon2 = rawLon.substring(decimal2Index + 1, rawLon.length());
      Serial.println(lon1);
      Serial.println(lon2);
      rawLon = lon1.substring(0, 2) + "." + lon1.substring(3, lon1.length()) + lon2;
      Serial.println(rawLon);

      char txtmsgArray[80];
      String txmsg = "https://www.google.com/maps/@" + rawLat + "," +  rawLon + ",15z";
      txmsg.toCharArray(txtmsgArray, 80);
      Serial.println(txtmsgArray);

      Serial.println("Sending reponse...");
      if (!fona.sendSMS(callerIDbuffer, txtmsgArray)) {
        Serial.println(F("Failed"));
      } else {
        Serial.println(F("Sent!"));
      }
      delay(3000);
      // delete the original msg after it is processed
      //   otherwise, we will fill up all the slots
      //   and then we won't be able to receive SMS anymore
      if (fona.deleteSMS(slot)) {
        Serial.println(F("OK!"));
      } else {
        Serial.println(F("Couldn't delete"));
      }
    }
  }
}

void TurnOnFona() {
  Serial.println("Turning on Fona: ");
  while (digitalRead(FONA_PS) == LOW) {
    digitalWrite(FONA_KEY, LOW);
  }
  digitalWrite(FONA_KEY, HIGH);
  delay(4000);
}

void TurnOffFona() {
  Serial.println("Turning off Fona ");
  while (digitalRead(FONA_PS) == HIGH) {
    digitalWrite(FONA_KEY, LOW);
  }
  digitalWrite(FONA_KEY, HIGH);
  delay(4000);
}
  • Using AT+CGPSINF=1 should give you NMEA formatted data. That may be of more use to you. – Majenko Mar 26 '16 at 21:25
2

Send the command:
AT+CGPSOUT=1

That should enable the output of the standard NMEA $GPGGA string which includes all the position information you should need in a format that either you can parse or use one of the many existing libraries to parse. It's not clear from the documentation if this will be a one time output or a 1 Hz output.

There are other NMEA messages available if you need them, see https://cdn-shop.adafruit.com/datasheets/SIM808_GPS_Application_Note_V1.00.pdf for details.

1

GPS is a positioning system: it doesn't do direction. If your software has serial information coming in, it can take the difference in readings and generate that data but GPS doesn't do it for you.

Some devices may add it to the standard, but that's a per-device feature. .

  • Op is asking for the hemisphere not the direction – Ian Turton Dec 30 '16 at 20:18
  • No he wasn't, that's "in addition" – Mark Williams Dec 31 '16 at 23:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.