Distance between coordinates

Hi all,
I am having trouble with getting the correct distance between my coordinates.
I am using the 1Sheeld to get the coordinates from my phone and an adafruit breakout (gps module) to get the coordinates of the device.
When I upload the code and turn everything on the serial monitor gives me an output of around 5,000 which is the same value as if one of the coordinates is (0,0). Despite me testing the code and knowing that individually the 1Sheeld and gps module give the correct coordinates, when I put it together the 1Sheeld produces an output of (0,0).
Summarising, the bulk of the code works, but I am unable to get the 1Sheeld to output the correct coordinates when combined with the code. If anyone has any idea how to fix this it would be greatly appreciated

#include <OneSheeld.h>
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial(3, 2);
Adafruit_GPS GPSM(&mySerial);
#define GPSECHO  false
#define CUSTOM_SETTINGS
#define INCLUDE_GPS_SHIELD
boolean usingInterrupt = false;
void useInterrupt(boolean);
float lat_gps,long_gps,lat_gpsm,long_gpsm;
float lonR1,lonR2,latR1,latR2;
char charlat [10];
char charlon [10];
char readings [80];
float dlat,dlon,a,e,d;
float R = 6371.00;
float toDegrees = 57.295779;
char sb[10];
void setup()
{
  { OneSheeld.begin();
  }
  Serial.begin(115200);
  GPSM.begin(9600);
  GPSM.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
  GPSM.sendCommand(PGCMD_ANTENNA);
  useInterrupt(true);
  delay(1000);
mySerial.println(F(PMTK_Q_RELEASE));
}
SIGNAL(TIMER0_COMPA_vect) {
char c = GPSM.read();
#ifdef UDR0
if (GPSECHO)
if (c) UDR0 = c;
#endif
}
void useInterrupt(boolean v) {
if (v) {
OCR0A = 0xAF;
TIMSK0 |= _BV(OCIE0A);
usingInterrupt = true;
  } else {
TIMSK0 &= ~_BV(OCIE0A);
usingInterrupt = false;
  }
  uint32_t timer = millis();   
    pinMode(LED_BUILTIN, OUTPUT);
}
void loop()
{
if (! usingInterrupt) {
char c = GPSM.read();
if (GPSECHO)
if (c) Serial.print(c);
  }
if (GPSM.newNMEAreceived()) {
if (!GPSM.parse(GPSM.lastNMEA()))
return;
  }
lat_gpsm = GPSM.latitudeDegrees;
long_gpsm = GPSM.longitudeDegrees;
  {
lat_gps = GPS.getLatitude();
long_gps = GPS.getLongitude();
  }
{ void calcDist();
lonR1 = long_gps*(PI/180);
lonR2 = long_gpsm*(PI/180);
latR1 = lat_gps*(PI/180);
latR2 = lat_gpsm*(PI/180);
dlon = lonR2 - lonR1;
dlat = latR2 - latR1;}
a = (sq(sin(dlat/2))) + cos(latR1) * cos(latR2) * (sq(sin(dlon/2)));
e = 2 * atan2(sqrt(a), sqrt(1-a)) ;
d = R * e;
Serial.print ( d );
}

nothing obviously wrong. You could add some println(s) to show dlon, dlat, etc before you "Haversine" them

you might consider using an equirectangular projection instead of Haversine. it's simpler and faster.

Why is that misplaced?
Would that have any influence on the 1Sheeld functioning correctly?

This fails to compile "a function-definition is not allowed here before '{' token"

void calcDist()
{
lonR1 = long_gps*(PI/180);
lonR2 = long_gpsm*(PI/180);
latR1 = lat_gps*(PI/180);
latR2 = lat_gpsm*(PI/180);
dlon = lonR2 - lonR1;
dlat = latR2 - latR1;}
a = (sq(sin(dlat/2))) + cos(latR1) * cos(latR2) * (sq(sin(dlon/2)));
e = 2 * atan2(sqrt(a), sqrt(1-a)) ;
d = R * e;
Serial.print ( d );
}

I tried and it still wouldn't compile, but I doubt that would have any impact on the 1Sheeld working.

I'm not missing any braces, when checked.
Error message "a function-definition is not allowed here before '{' token"

#include <OneSheeld.h>
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial(3, 2);
Adafruit_GPS GPSM(&mySerial);
#define GPSECHO  false
#define CUSTOM_SETTINGS
#define INCLUDE_GPS_SHIELD
boolean usingInterrupt = false;
void useInterrupt(boolean);
float lat_gps, long_gps, lat_gpsm, long_gpsm;
float lonR1, lonR2, latR1, latR2;
char charlat [10];
char charlon [10];
char readings [80];
float dlat, dlon, a, e, d;
float R = 6371.00;
float toDegrees = 57.295779;
char sb[10];
void setup()
{
  { OneSheeld.begin();
  }
  Serial.begin(115200);
  GPSM.begin(9600);
  GPSM.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
  GPSM.sendCommand(PGCMD_ANTENNA);
  useInterrupt(true);
  delay(1000);
  mySerial.println(F(PMTK_Q_RELEASE));
}
SIGNAL(TIMER0_COMPA_vect) {
  char c = GPSM.read();
#ifdef UDR0
  if (GPSECHO)
    if (c) UDR0 = c;
#endif
}
void useInterrupt(boolean v) {
  if (v) {
    OCR0A = 0xAF;
    TIMSK0 |= _BV(OCIE0A);
    usingInterrupt = true;
  } else {
    TIMSK0 &= ~_BV(OCIE0A);
    usingInterrupt = false;
  }
  uint32_t timer = millis();
  pinMode(LED_BUILTIN, OUTPUT);
}
void loop()
{
  if (! usingInterrupt) {
    char c = GPSM.read();
    if (GPSECHO)
      if (c) Serial.print(c);
  }
  if (GPSM.newNMEAreceived()) {
    if (!GPSM.parse(GPSM.lastNMEA()))
      return;
  }
  lat_gpsm = GPSM.latitudeDegrees;
  long_gpsm = GPSM.longitudeDegrees;
  {
    lat_gps = GPS.getLatitude();
    long_gps = GPS.getLongitude();
  }
  void calcDist()
  {
    lonR1 = long_gps * (PI / 180);
    lonR2 = long_gpsm * (PI / 180);
    latR1 = lat_gps * (PI / 180);
    latR2 = lat_gpsm * (PI / 180);
    dlon = lonR2 - lonR1;
    dlat = latR2 - latR1;
  }
  a = (sq(sin(dlat / 2))) + cos(latR1) * cos(latR2) * (sq(sin(dlon / 2)));
  e = 2 * atan2(sqrt(a), sqrt(1 - a)) ;
  d = R * e;
  Serial.print ( d );
}
  void calcDist()
  {
    lonR1 = long_gps * (PI / 180);
    lonR2 = long_gpsm * (PI / 180);
    latR1 = lat_gps * (PI / 180);
    latR2 = lat_gpsm * (PI / 180);
    dlon = lonR2 - lonR1;
    dlat = latR2 - latR1;
  }

That's where that function ends.
So why does it continue beyond that?

Thanks, it compiled.

But Im having an issue with the serial monitor, when the 1Sheeld is off it says the distance is roughly 5,000km (the GPS module works but the 1Sheeld when combined doesn't) and when it turns on it just goes weird and displays "nananana".

#include <OneSheeld.h>
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial(3, 2);
Adafruit_GPS GPSM(&mySerial);
#define GPSECHO  false
#define CUSTOM_SETTINGS
#define INCLUDE_GPS_SHIELD
boolean usingInterrupt = false;
void useInterrupt(boolean);
float lat_gps, long_gps, lat_gpsm, long_gpsm;
float lonR1, lonR2, latR1, latR2;
char charlat [10];
char charlon [10];
char readings [80];
float dlat, dlon, a, e, d;
float R = 6371.00;
float toDegrees = 57.295779;
char sb[10];
void setup()
{
  { OneSheeld.begin();
  }
  Serial.begin(115200);
  GPSM.begin(9600);
  GPSM.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
  GPSM.sendCommand(PGCMD_ANTENNA);
  useInterrupt(true);
  delay(1000);
  mySerial.println(F(PMTK_Q_RELEASE));
}
SIGNAL(TIMER0_COMPA_vect) {
  char c = GPSM.read();
#ifdef UDR0
  if (GPSECHO)
    if (c) UDR0 = c;
#endif
}
void useInterrupt(boolean v) {
  if (v) {
    OCR0A = 0xAF;
    TIMSK0 |= _BV(OCIE0A);
    usingInterrupt = true;
  } else {
    TIMSK0 &= ~_BV(OCIE0A);
    usingInterrupt = false;
  }
  uint32_t timer = millis();
  pinMode(LED_BUILTIN, OUTPUT);
}
void loop()
{
  if (! usingInterrupt) {
    char c = GPSM.read();
    if (GPSECHO)
      if (c) Serial.print(c);
  }
  if (GPSM.newNMEAreceived()) {
    if (!GPSM.parse(GPSM.lastNMEA()))
      return;
  }
  lat_gpsm = GPSM.latitudeDegrees;
  long_gpsm = GPSM.longitudeDegrees;
  {
    lat_gps = GPS.getLatitude();
    long_gps = GPS.getLongitude();
  }
}
  void calcDist()
  {
    lonR1 = long_gps * (PI / 180);
    lonR2 = long_gpsm * (PI / 180);
    latR1 = lat_gps * (PI / 180);
    latR2 = lat_gpsm * (PI / 180);
    dlon = lonR2 - lonR1;
    dlat = latR2 - latR1;
  
  a = (sq(sin(dlat / 2))) + cos(latR1) * cos(latR2) * (sq(sin(dlon / 2)));
  e = 2 * atan2(sqrt(a), sqrt(1 - a)) ;
  d = R * e;
  Serial.print ( d );
  }

nannanna etc..
and it says 000.000.000 when its not on.

Despite me testing the code and knowing that individually the 1Sheeld and gps module give the correct coordinates, when I put it together the 1Sheeld produces an output of (0,0).

Good grief that sketch is a mess. For example, why do you call the GPS device "GPSM"?!?

    Adafruit_GPS GPSM(&mySerial);

And what is this supposed to do?

  lat_gpsm = GPSM.latitudeDegrees;
  long_gpsm = GPSM.longitudeDegrees;
  {
    lat_gps = GPSM.getLatitude();
    long_gps = GPSM.getLongitude();
  }

That doesn't compile. Here's a simpler sketch that uses my NeoGPS library:

#include <NMEAGPS.h>
#include <NeoSWSerial.h>
NeoSWSerial gps_port(3, 2);

NMEAGPS gps;
gps_fix fix;

NeoGPS::Location_t otherPlace( (float)51.508131, (float)-0.128002 ); // London

void setup()
{
  Serial.begin(115200);

  gps_port.begin(9600);
  gps_port.println( F("$PMTK220,1000*1F\r\n"
                      "$PGCMD,33,1*6C") );
}

void loop()
{
  if (gps.available( gps_port )) {
    fix = gps.read();

    if (fix.valid.location) {
      
      float d = fix.location.DistanceKm( otherPlace );
      Serial.print( d );
      Serial.println( F(" km to London") );
    }
  }
}

WAY SIMPLER. Notice how easy it is to calculate distance. It's also faster, smaller and more accurate. When you are close to the otherPlace, the NeoGPS distance is much more accurate. It saves the GPS lat/long with more accuracy, and the extra digits are also used in distance and bearing calculations.

The original sketch used 10196 bytes of program space and 793 bytes of RAM.
The NeoGPS sketch uses 9592 bytes of program space and 365 bytes of RAM, less than half the RAM!

The sketch also uses NeoSWSerial instead of SoftwareSerial. SoftwareSerial is very, very inefficient because it disables interrupts for long periods of time. This can interfere with your sketch or libraries. AltSoftSerial is the best, but it can only be used on pins 8 & 9 (of an UNO).

If you'd like to try it, NeoGPS is available from the Arduino IDE menu Sketch -> Include Library -> Manage Libraries.

Cheers,
/dev

Im in the process of trying this NeoGPS, however, it had a problem with NeoSWSerial.
I tried to merge my code and your code put it didn't compile.
Error code "var/folders/8f/kg3grh3926sb0jx_m72x3wz80000gn/T/arduino_modified_sketch_756359/sketch_jan07a.ino:5:25: fatal error: NeoSWSerial.h: No such file or directory
#include <NeoSWSerial.h>

  • ^*
    compilation terminated.
    exit status 1
    Error compiling for board Arduino/Genuino Uno."
#include <NMEAGPS.h>
#include <OneSheeld.h>
#define CUSTOM_SETTINGS
#define INCLUDE_GPS_SHIELD
#include <NeoSWSerial.h>
NeoSWSerial gps_port(3, 2);

NMEAGPS gps;
gps_fix fix;

NeoGPS::Location_t otherPlace( (float)lat_gps, (float)lon_gps ); // User

void setup()
{
  Serial.begin(115200);

  gps_port.begin(9600);
  gps_port.println( F("$PMTK220,1000*1F\r\n"
                      "$PGCMD,33,1*6C") );
}

void loop()
{
  { lat_gps = GPS.getLatitude();
    long_gps = GPS.getLongitude();
  }
  if (gps.available( gps_port )) {
    fix = gps.read();

    if (fix.valid.location) {

      float d = fix.location.DistanceKm( otherPlace );
      Serial.print( d );
      Serial.println( F(" km to User") );
    }
  }
}

You'll have to download NeoSWSerial from the link above. Install instructions there, too.

... and don't modify the sketch I posted before you try it.

#include <OneSheeld.h>
#define CUSTOM_SETTINGS
#define INCLUDE_GPS_SHIELD
   ...

 { lat_gps = GPS.getLatitude();
    long_gps = GPS.getLongitude();
  }

These lines are bogus.

The latitude and longitude are inside this "fix" structure:

      fix = gps.read();

You could ask for the lat/lon pieces, but you don't need them. You can just use the fix "location" (which has a lat & lon inside it) to calculate the distance from another location:

    float d = fix.location.DistanceKm( otherPlace );

All the pieces you can get from the "fix" structure are described on the NeoGPS Data Model page.

And don't calculate the distance if you don't have a valid location:

  if (fix.valid.location) {

Sometimes, the GPS device may not have good satellite reception, and it won't know the current location.

Cheers,
/dev

The overall aim of this project is to get an autonomous robot to reach a person in need of assistance.
So the robot will need to get their location (lon_gps and lat_gps) and its own location (lat_gpsm, lon_gpsm). It will work out the distance and bearing between those points and then make its own way there.
So the position can't be a fixed location, the code will need to find it.

OK, that's easy enough to do. Instead of hard-coding a location at the top, you will set the lat/Lon pieces of the "other place" Location_t variable, and calculate distance and bearing from the GPS location (the "fix.location" variable).

But to begin, start with unmodified examples and make sure you understand them. There's no reason to add those unnecessary includes or defines.

Then add features, one at a time, so it's easy to see what caused a new error.

Cheers,
/dev