Store coordinates in a variable using TinyGPSPlus

I want to store the coordinates with 6 decimals. With serial works

Serial.println(gps.location.lat(),6);       //55.121421

I want the same value in a variable, I tried:

double lat=(gps.location.lat(),6);     //display 6
double lat=(gps.location.lat());                //display 55.12

Try

double lat=gps.location.lat(); 
Serial.println(lat, 6);

It is stored in lat with all the decimal places, but the default with print is 2 places unless you add the extra parameter.

FYI: In Arduino land double and float are the same (4 bytes). .

Ahh ok, thanks Im a noob on arduino.

Is possible limit the number of decimals to store? If I want for example only 6.

Is possible limit the number of decimals to store?

No.

I want to store the coordinates with 6 decimals.

If 55.121421 is an example coordinate, you can’t store all 8 significant digits in a [

float

](Floating-point arithmetic - Wikipedia). A float has about 7 significant digits.

NeoGPS is a library I wrote to have increased accuracy. It is smaller and faster than other libraries, and the example programs are structured correctly. It merges all information sent by the GPS device (i.e., all sentences) into a single fix structure. It can also be configured to parse only the fields and messages you really need, saving even more program space, RAM and time.

The coordinate type in NeoGPS retains 10 significant digits. It also has Distance, Bearing and Offset functions that provide more accurate results. Although a coordinate is internally stored as a long int, you can print it as if it were a floating-point value (see NMEAloc.ino).

Is possible limit the number of decimals to store? If I want for example only 6.

There are integers, like 55, that don’t have any “decimals”, and floating-point numbers, like 55.121421, that have “significant digits”.

That’s because a float has two internal parts: an exponent (like 5 for 25) and a mantissa. The floating point value is 2exponent * mantissa. So for 55.121421, the exponent would be 5 and the mantissa would be 1.722544:

    2[sup]5[/sup] * 1.722544 =
    32 * 1.722544 = 55.121421

The mantissa has only 7 digits.

But the number of “decimals” is not related to that. A floating point value could be 0.000000001234567. Although that’s 15 decimals, it only has 7 significant digits, and would be represented by an exponent of -30 and a mantissa of 1.325606: 2-30 * 1.325606.

You usually store a value as an integer or a float (with all its “decimals” :slight_smile: ), and print it later in the form you want to “see”.

Cheers,
/dev

How could truncate or round?
From this 50.2030405060… to 50.203040

How could truncate or round?

Why on earth would you want to? The data should be as accurate as possible. If you want to PRINT a value with some less precision, that is a completely separate issue. And, you have been how to do THAT.

I just want to calculate the coordinates for example 20m Nord from where I am.

Mr07:
How could truncate or round?
From this 50.2030405060… to 50.203040

You can’t do that with a float. You can print it with more or fewer digits:

  Serial.print( lat, 10 );
  Serial.print( lat, 6 );

… but anything more than 5 decimals is useless. A floating-point lat only has 7 significant digits, and 2 are used for the “50”. You can’t do floating-point math on anything more than 7 digits.

I just want to calculate the coordinates for example 20m Nord from where I am.

That doesn’t require truncation or rounding. That is calculating a new location from an original location, a distance and a bearing. And you need very accurate values. Most GPS devices will give a location that wanders around by 3m to 100m, depending on satellite reception. So 20m north of your location will also wander around. :stuck_out_tongue:

Here is a NeoGPS sketch that does it, but it uses the a special NeoGPS location type, called Location_t:

#include "NMEAGPS.h"

NMEAGPS gps;
#define gps_port Serial1

const float METERS_TO_RADIANS = 1.0 / (NeoGPS::Location_t::EARTH_RADIUS_KM * 1000.0);
const float NORTH_RADIANS     = 0.0;

void setup()
{
  Serial.begin( 9600 );
  Serial.println( F("Mr07 example") );
  
  gps_port.begin( 9600 );
}

void loop()
{
  // Read and parse GPS data, if there is any.
  while (gps.available( gps_port )) {

    // A complete fix is ready
    gps_fix fix = gps.read();

    // A fix may not have a valid location.  Check first.
    if (fix.valid.location) {

      // Display my location
      Serial.print( F("Me      : ") );
      printLoc( fix.location );
      Serial.println();

      // Display another location, 20m north of my location
      NeoGPS::Location_t other( fix.location ); // start at my location

      other.OffsetBy( 20.0 * METERS_TO_RADIANS, NORTH_RADIANS ); // step 20m nord
      Serial.print( F("20m nord: ") );
      printLoc( other );
      Serial.println();
      Serial.println();
    }
  }
}

//-----------------------------
//  Print a location structure
void printLoc( NeoGPS::Location_t loc )
{
  printL( loc.lat() );
  Serial.print( ',' );
  printL( loc.lon() );
}

//-----------------------------
// Print a latitude or a longitude
void printL( int32_t degE7 )
{
  // Extract and print negative sign
  if (degE7 < 0) {
    degE7 = -degE7;
    Serial.print( '-' );
  }

  // Whole degrees
  int32_t deg = degE7 / 10000000L;
  Serial.print( deg );
  Serial.print( '.' );

  // Get fractional degrees
  degE7 -= deg*10000000L;

  // Print leading zeroes, if needed
  int32_t factor = 1000000L;
  while ((degE7 < factor) && (factor > 1L)){
    Serial.print( '0' );
    factor /= 10L;
  }
  
  // Print fractional degrees
  Serial.print( degE7 );
}

You may have to change the gps_port to be your GPS serial port. If you decide to try it, be sure to follow the NeoGPS Installation instructions.

Cheers,
/dev

Sounds interesting but that library seems to be for advanced programmers and Im a bit noob. :/ I will try anyways.

Works nice! With tinyGPS I got the course that I have when im moving.

Serial.print(gps.course());

I already do it between 2 points.

float course = fix.location.BearingToDegrees(other);
Serial.println(course2);

How can I get the course send by gps?

Sorry for my english.

How can I get the course send by gps?

The GPS doesn't send a course. At least mine doesn't. A course is a collection of 2 or more way points that a GPS does report.

He might mean "heading". That is available, though it is only valid when moving.

How can I get the course send by gps?

Yes, that's the heading:

 float course = fix.heading(); // degrees

And it may not be valid yet, so you may want to guard it:

if (fix.valid.heading) {
  float course = fix.heading();

  if (course > 5.0) {
    // fast enough to be a good number
       .
       .
       .

All these fields are listed on the Data Model page.

Cheers, /dev

Thats what I wanted to find, thanks man!