SparkFun Forums 

Where electronics enthusiasts find answers.

Tips and questions relating to the GPS modules from SFE
By acca
#102876
Hi

I'm a new user of Arduino. I just bought a Arduino Mega, a gps module eb-85a and the sparkfun Arduino Gps Shield.

I try to see the gps output using the TinyGPS library example "test_with_gps_device".

The shield is connected to the Arduino Mega and the Gps is connected to the shield.

The Dline/uart switch is on dline

When i upload the example code and launch the serial Monitor, all i can see is :
Code: Select all
Testing TinyGPS library v. 9
by Mikal Hart

Sizeof(gpsobject) = 103


The used code is :
Code: Select all
#include <NewSoftSerial.h>
#include <TinyGPS.h>

/* This sample code demonstrates the normal use of a TinyGPS object.
   It requires the use of NewSoftSerial, and assumes that you have a
   4800-baud serial GPS device hooked up on pins 2(rx) and 3(tx).
*/

TinyGPS gps;
NewSoftSerial nss(2,3);

void gpsdump(TinyGPS &gps);
bool feedgps();
void printFloat(double f, int digits = 2);

void setup()
{
  Serial.begin(115200);
  nss.begin(4800);
  
  Serial.print("Testing TinyGPS library v. "); Serial.println(TinyGPS::library_version());
  Serial.println("by Mikal Hart");
  Serial.println();
  Serial.print("Sizeof(gpsobject) = "); Serial.println(sizeof(TinyGPS));
  Serial.println();
}

void loop()
{
  bool newdata = false;
  unsigned long start = millis();

  // Every 5 seconds we print an update
  while (millis() - start < 5000)
  {
    if (feedgps())
      newdata = true;
  }
  
  if (newdata)
  {
    Serial.println("Acquired Data");
    Serial.println("-------------");
    gpsdump(gps);
    Serial.println("-------------");
    Serial.println();
  }
}

void printFloat(double number, int digits)
{
  // Handle negative numbers
  if (number < 0.0)
  {
     Serial.print('-');
     number = -number;
  }

  // Round correctly so that print(1.999, 2) prints as "2.00"
  double rounding = 0.5;
  for (uint8_t i=0; i<digits; ++i)
    rounding /= 10.0;
  
  number += rounding;

  // Extract the integer part of the number and print it
  unsigned long int_part = (unsigned long)number;
  double remainder = number - (double)int_part;
  Serial.print(int_part);

  // Print the decimal point, but only if there are digits beyond
  if (digits > 0)
    Serial.print("."); 

  // Extract digits from the remainder one at a time
  while (digits-- > 0)
  {
    remainder *= 10.0;
    int toPrint = int(remainder);
    Serial.print(toPrint);
    remainder -= toPrint; 
  } 
}

void gpsdump(TinyGPS &gps)
{
  long lat, lon;
  float flat, flon;
  unsigned long age, date, time, chars;
  int year;
  byte month, day, hour, minute, second, hundredths;
  unsigned short sentences, failed;

  gps.get_position(&lat, &lon, &age);
  Serial.print("Lat/Long(10^-5 deg): "); Serial.print(lat); Serial.print(", "); Serial.print(lon); 
  Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms.");
  
  feedgps(); // If we don't feed the gps during this long routine, we may drop characters and get checksum errors

  gps.f_get_position(&flat, &flon, &age);
  Serial.print("Lat/Long(float): "); printFloat(flat, 5); Serial.print(", "); printFloat(flon, 5);
  Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms.");

  feedgps();

  gps.get_datetime(&date, &time, &age);
  Serial.print("Date(ddmmyy): "); Serial.print(date); Serial.print(" Time(hhmmsscc): "); Serial.print(time);
  Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms.");

  feedgps();

  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  Serial.print("Date: "); Serial.print(static_cast<int>(month)); Serial.print("/"); Serial.print(static_cast<int>(day)); Serial.print("/"); Serial.print(year);
  Serial.print("  Time: "); Serial.print(static_cast<int>(hour)); Serial.print(":"); Serial.print(static_cast<int>(minute)); Serial.print(":"); Serial.print(static_cast<int>(second)); Serial.print("."); Serial.print(static_cast<int>(hundredths));
  Serial.print("  Fix age: ");  Serial.print(age); Serial.println("ms.");
  
  feedgps();

  Serial.print("Alt(cm): "); Serial.print(gps.altitude()); Serial.print(" Course(10^-2 deg): "); Serial.print(gps.course()); Serial.print(" Speed(10^-2 knots): "); Serial.println(gps.speed());
  Serial.print("Alt(float): "); printFloat(gps.f_altitude()); Serial.print(" Course(float): "); printFloat(gps.f_course()); Serial.println();
  Serial.print("Speed(knots): "); printFloat(gps.f_speed_knots()); Serial.print(" (mph): ");  printFloat(gps.f_speed_mph());
  Serial.print(" (mps): "); printFloat(gps.f_speed_mps()); Serial.print(" (kmph): "); printFloat(gps.f_speed_kmph()); Serial.println();

  feedgps();

  gps.stats(&chars, &sentences, &failed);
  Serial.print("Stats: characters: "); Serial.print(chars); Serial.print(" sentences: "); Serial.print(sentences); Serial.print(" failed checksum: "); Serial.println(failed);
}
  
bool feedgps()
{
  while (nss.available())
  {
    if (gps.encode(nss.read()))
      return true;
  }
  return false;
}
I tryed inverting NewSoftSerial nss(2,3); to NewSoftSerial nss(3,2); but it does nothing

I precise that im a newbie

Anyone could help me please ?
By SFE-Mike
#103699
One possible problem is that the code expects a GPS that's running at 4,800 baud. The EB-85A (now FV-M8) looks like it has a default baud rate of 38,400. Try changing the 4,800 to 38,400 and see if that helps (also check to make sure that the softserial library can handle speeds as fast as 38,400).

I think you're also right about swapping the serial pins for softserial. Also be sure you've flipped the switch on the GPS Shield to DLINE.

If that doesn't work, it's sometimes easier to test with the minimum possible configuration. Since the GPS will begin sending fix information on powerup, you can connect just the GPS TX to the Arduino RX, and leave the Arduino TX free to talk to the serial console on the PC. If you can jumper from the Arduino to the Shield without plugging it in, try connecting just these pins:

RX - RX
GND - GND
5V - 5V
3.3V - 3.3V

and run this code:
Code: Select all
void setup()
{
	Serial.begin(38400);	// opens serial port, sets data rate
}

void loop()
{
	// send data only when you receive data:
	if (Serial.available() > 0)
	{
		Serial.print(Serial.read(), BYTE);
	}
}
Hopefully you'll see lots of data start streaming across, and can go from there.
By acca
#103700
Hi thank you very much

I didn't updated but my problem seems to come from the newsoftserial lib wich is not compatible with Arduino Mega

I just plugged the gps tx and rx to a hard serial port and all is ok.

Regards !
By SFE-Mike
#103716
D'oh! Thanks for letting us know (I wasn't aware of that!) And glad everything's working!
By ycha0723
#116620
Hi there
I have the same gps and setup with acca
I am trying to access the values of lat and lon from
gps.get_position(&lat, &lon, &age);
but i keep getting an error
I am trying to calculate the distance between two points
Code: Select all
#include <NewSoftSerial.h>
#include <TinyGPS.h>
//#include <math.h>

/* This sample code demonstrates the normal use of a TinyGPS object.
   It requires the use of NewSoftSerial, and assumes that you have a
   38400-baud serial GPS device hooked up on pins 18(TX1) and 19(RX1).
*/

TinyGPS gps;
//NewSoftSerial nss(2, 3);

void gpsdump(TinyGPS &gps);
bool feedgps();
void printFloat(double f, int digits = 2);
void distance_calc(double lat1, double lon1, double lat2, double lon2, double *d);
double DegtoRad(double deg);  // This shall convert degree value to radians

const double  EarthRadius = 6371; // Mean Earth radius is 6371km
#define GPS_Port Serial1
void setup()
{
  Serial.begin(115200);
  GPS_Port.begin(38400);
  
  Serial.print("Testing TinyGPS library v. "); Serial.println(TinyGPS::library_version());
  Serial.println("by Mikal Hart and edited by Yisheng Chang");
  Serial.println();
  Serial.print("Sizeof(gpsobject) = "); Serial.println(sizeof(TinyGPS));
  Serial.println();
}

void loop()
{
  bool newdata = false;
  unsigned long start = millis();

  // Every 2.5 seconds we print an update
  while (millis() - start < 2500)
  {
    if (feedgps())
      
      newdata = true;
  }
  
  if (newdata)
  {

    
    Serial.println("Acquired Data");
    Serial.println("-------------");
    gpsdump(gps);
    Serial.println("-------------");
    Serial.println();
    
    /*right after printing out the gps data, access the lat and lon and save it in a */
    int i = 0;
    /*store immediatley in array*/
    double lat[i] = *lat;    ////////////////////////////////problem here is how to access the value stored in variable 'lat' from get_position of function gpsdump()
    double lon[i] = *lon;
    
      if( i > 0 ) // means there are atleast 2 points available in each array
      {
        lat[i] = lat1;
        lon[i] = lon1;
        lat[i-1] = lat2;
        lon[i-1] = lon2;
      
        /*Calculate distance between two points*/
        double Distance;
        distance_calc(lat1, lon1, lat2, lon2, &Distance);
        Serial.print("Distance between two points is ");
        printFloat(Distance);
        Serial.println();
      
      }
    
      i++;
    
    
   
    
  }
}

void printFloat(double number, int digits)
{
  // Handle negative numbers
  if (number < 0.0)
  {
     Serial.print('-');
     number = -number;
  }

  // Round correctly so that print(1.999, 2) prints as "2.00"
  double rounding = 0.5;
  for (uint8_t i=0; i<digits; ++i)
    rounding /= 10.0;
  
  number += rounding;

  // Extract the integer part of the number and print it
  unsigned long int_part = (unsigned long)number;
  double remainder = number - (double)int_part;
  Serial.print(int_part);

  // Print the decimal point, but only if there are digits beyond
  if (digits > 0)
    Serial.print("."); 

  // Extract digits from the remainder one at a time
  while (digits-- > 0)
  {
    remainder *= 10.0;
    int toPrint = int(remainder);
    Serial.print(toPrint);
    remainder -= toPrint; 
  } 
}

void gpsdump(TinyGPS &gps)
{
  long lat, lon;
  double lat1, lon1;
  float flat, flon;
  unsigned long age, date, time, chars;
  int year;
  byte month, day, hour, minute, second, hundredths;
  unsigned short sentences, failed;

  gps.get_position(&lat, &lon, &age);
  Serial.print("Lat/Long(10^-5 deg): \t"); Serial.print(lat); Serial.print(", "); Serial.print(lon); 
  Serial.print("\t Fix age: "); Serial.print(age); Serial.println("ms.");

  feedgps(); // If we don't feed the gps during this long routine, we may drop characters and get checksum errors

  gps.f_get_position(&flat, &flon, &age);
  Serial.print("Lat/Long(float): \t"); printFloat(flat, 5); Serial.print(", "); printFloat(flon, 5);
  Serial.print("\t Fix age: "); Serial.print(age); Serial.println("ms.");

  feedgps();

  gps.get_datetime(&date, &time, &age);
  Serial.print("Date(ddmmyy): "); Serial.print(date); Serial.print("\t Time(hhmmsscc): "); Serial.print(time);
  Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms.");

  feedgps();

  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  Serial.print("Date: "); Serial.print(static_cast<int>(month)); Serial.print("/"); Serial.print(static_cast<int>(day)); Serial.print("/"); Serial.print(year);
  Serial.print("\t\t Time: "); Serial.print(static_cast<int>(hour)); Serial.print(":"); Serial.print(static_cast<int>(minute)); Serial.print(":"); Serial.print(static_cast<int>(second)); Serial.print("."); Serial.print(static_cast<int>(hundredths));
  Serial.print("\t Fix age: ");  Serial.print(age); Serial.println("ms.");
  
  feedgps();

  Serial.print("Alt(cm): "); Serial.print(gps.altitude()); Serial.print("\t\t Course(10^-2 deg): "); Serial.println(gps.course()); 
  Serial.print("Alt(float): "); printFloat(gps.f_altitude()); Serial.print("\t Course(float): "); printFloat(gps.f_course()); Serial.println();
  Serial.print("Speed(10^-2 knots): "); Serial.print(gps.speed());Serial.print("\t Speed(knots):"); printFloat(gps.f_speed_knots()); Serial.println();
  Serial.print("Speed(mph):");  printFloat(gps.f_speed_mph());Serial.print("\t\t (mps):"); printFloat(gps.f_speed_mps()); Serial.print("\t\t (kmph):"); 
  printFloat(gps.f_speed_kmph()); Serial.println();

  feedgps();

  gps.stats(&chars, &sentences, &failed);
  Serial.print("Characters: "); Serial.print(chars); Serial.print("\t sentences: "); Serial.print(sentences); Serial.print("\t\t failed checksum: "); Serial.println(failed);
}
  
bool feedgps()
{
  while (GPS_Port.available())
  {
    if (gps.encode(GPS_Port.read()))
      GPS_Port.flush();
      return true;
  }    
  return false;
}



/*
    This function takes a value in degrees and converts it into radians
    Arguments:
        double deg : the degree input 
    Returned values:
        double rad : returns the input value in radian
*/


double DegtoRad(double deg)
{ 
    double rad;
    rad = deg*PI/180;
    return rad;
}


/*
    This is the Haversine function.It calculates the distance between two points given their latitude and longitude of the two points
    The mean radius of the Earth is used for the calculation. Since the Earth is slightly spherical, the Earth's radius varies when measuring 
    from different points on the Earth's surface to its core.
    Arguments:
        double lat1 : latitude of first point 
        double lon1 : longitude of first point
        double lat2 : latitude of second point
        double lon2 : longitude of second point
    Returned values:
        double d : distance between two points in kilometers  
*/
void distance_calc(double lat1, double lon1, double lat2, double lon2, double *d)
{
    double Lat = (lat2-lat1);
    double Lon = (lon2-lon1); 
    double dLat = DegtoRad(Lat);
    double dLon = DegtoRad(Lon); 
    double a = sin(dLat/2) * sin(dLat/2) + cos(DegtoRad(lat1)) * cos(DegtoRad(lat2)) * sin(dLon/2) * sin(dLon/2); 
    double c = 2 * (atan2(sqrt(a), sqrt(1-a)));  
    // The atan2() function computes the principal value of the arc tangent of __y / __x, using the signs of both arguments to determine the quadrant of the return value. 
    // The returned value is in the range [-pi, +pi] radians.
    *d = EarthRadius * c;

}
By akmishra_99
#119259
Hello,

I had tinygps program working on my arduino , however I used arduino18 as development environment, but when I switched to arduino0022 development environmnent nothing works all I get is

"Testing TinyGPS library v .9
By Michael Hart

sizeof(gpsobject) = 103"

what could be wrong.


-Thanks
akmishra_99