Dear all,
This is my first Arduino project, so my code is quite copy and pasted (apologies in advance if it is difficult to follow). But essentially the program should gather two sets of coordinates from a GPS module and the users phone (using the 1Sheeld) and work out the bearing and distance between them.
My issue is with calculating the distance and the bearing. Initially when I simply put the whole formula before the void setup it just gave an output of 0.000 and 0.000, so I have moved it around. Now there is an error labelled "'CalcDistance' cannot be used as a function"
If anyone has any idea of how to either clean up my code (as it is using a lot of memory) or how to get the distance it would be much appreciated.
Code:
#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
//convert degrees to radians
double dtor(double fdegrees)
{
return(fdegrees * PI / 180);
}
//Convert radians to degrees
double rtod(double fradians)
{
return(fradians * 180.0 / PI);
}
boolean usingInterrupt = false;
void useInterrupt(boolean);
float lat_gps;
float long_gps;
float lat_gpsm;
float long_gpsm;
char charlat [10];
char charlon [10];
char readings [80];
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(PMTK_Q_RELEASE);
long printableDist;
int printableBearing;
float CalcDistance;
float CalcBearing;
printableDist = CalcDistance(0,0,0,0);
printableBearing = CalcBearing(0,0,0,0);
}
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();
void loop()
{
if (! usingInterrupt) {
char c = GPSM.read();
if (GPSECHO)
if (c) Serial.print(c);
}
if (GPSM.newNMEAreceived()) {
if (!GPSM.parse(GPSM.lastNMEA()))
return;
}
if (timer > millis()) timer = millis();
if (millis() - timer > 2000) {
timer = millis();
lat_gpsm = GPSM.latitudeDegrees;
Serial.print(", ");
long_gpsm = GPSM.longitudeDegrees;
}
{
lat_gps = GPS.getLatitude();
long_gps = GPS.getLongitude();
}
//Calculate distance from lat_gpsm/long_gpsm to lat_gps/long_gps using haversine formula
//Note lat_gpsm/long_gpsm/lat_gps/long_gps must be in radians
//Returns distance in feet
long CalcDistance(double lat_gpsm, double long_gpsm, double lat_gps, double long_gps)
{
double dlon, dlat, a, c;
double dist = 0.0;
dlon = dtor(long_gps - long_gpsm);
dlat = dtor(lat_gps - lat_gpsm);
a = pow(sin(dlat/2),2) + cos(dtor(lat_gpsm)) * cos(dtor(lat_gps)) * pow(sin(dlon/2),2);
c = 2 * atan2(sqrt(a), sqrt(1-a));
dist = 20925656.2 * c; //radius of the earth (6378140 meters) in feet 20925656.2
return( (long) dist + 0.5);
}
//Calculate bearing from lat_gpsm/long_gpsm to lat_gps/long_gps
//Note lat_gpsm/long_gpsm/lat_gps/long_gps must be in radians
//Returns bearing in degrees
int CalcBearing(double lat_gpsm, double long_gpsm, double lat_gps, double long_gps)
{
lat_gpsm = dtor(lat_gpsm);
long_gpsm = dtor(long_gpsm);
lat_gps = dtor(lat_gps);
long_gps = dtor(long_gps);
//determine angle
double bearing = atan2(sin(long_gps-long_gpsm)*cos(lat_gps), (cos(lat_gpsm)*sin(lat_gps))-(sin(lat_gpsm)*cos(lat_gps)*cos(long_gps-long_gpsm)));
//convert to degrees
bearing = rtod(bearing);
//use mod to turn -90 = 270
bearing = fmod((bearing + 360.0), 360);
return (int) bearing + 0.5;
}
Serial.print(printableBearing);
Serial.println(printableDist);
}