# direction (course) from tinygps plus library ??

**URL:** <https://forum.arduino.cc/t/direction-course-from-tinygps-plus-library/448207>\
**Category:** Programming\
**Created:** [March 29, 2017, 2:41am UTC](https://forum.arduino.cc/t/direction-course-from-tinygps-plus-library/448207 "2017-03-29T02:41:24Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![loyal979](https://avatars.discourse-cdn.com/v4/letter/l/b782af/32.png) [@loyal979](https://forum.arduino.cc/u/loyal979)\
**Post date:** [March 29, 2017, 2:41am UTC](https://forum.arduino.cc/t/direction-course-from-tinygps-plus-library/448207/1 "2017-03-29T02:41:24Z")

</div>

Hi all,

Im trying to calculate or printing the current course in deg. by using the function gps.course.deg() from tinygps library to give me my current course. but the course is jumping around and Im not sure how the course is being calculated.

is there a way to fix that or any another way to calculate the current course by using the lat and lon ?

a copy of my code is attached below

Thanks

[gps.ino](https://forum.arduino.cc/uploads/short-url/d0xl8CgrOhkXh7CqbZBargmjpVp.ino) (3.32 KB)

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [March 29, 2017, 10:40am UTC](https://forum.arduino.cc/t/direction-course-from-tinygps-plus-library/448207/2 "2017-03-29T10:40:34Z")

</div>

> a copy of my code is attached below

Why? Your code is short enough to just post.

```arduino
#include <SoftwareSerial.h>
#include <TinyGPS++.h>

#define RXPin 8
#define TXPin 7
#define GPSBaud 9600
#define ConsoleBaud 115200

// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);

// The TinyGPS++ object
TinyGPSPlus gps;
unsigned long lastUpdateTime = 0;

#define des_LAT 44.88285
#define des_LNG -68.67253

/* This example shows a basic framework for how you might
  use course and distance to guide a person (or a drone)
  to a destination.  This destination is the Eiffel Tower.
  Change it as required.

  The easiest way to get the lat/long coordinate is to
  right-click the destination in Google Maps (maps.google.com),
  and choose "What's here?".  This puts the exact values in the
  search box.
*/

void setup()
{
  Serial.begin(ConsoleBaud);
  ss.begin(GPSBaud);

}

void loop()
{
  // If any characters have arrived from the GPS,
  // send them to the TinyGPS++ object
  while (ss.available() > 0)
    gps.encode(ss.read());

  // Every 5 seconds, do an update.
  if (millis() - lastUpdateTime >= 5000)
  {
    lastUpdateTime = millis();
    Serial.println();

    // Establish our current status
    double distanceToDestination = TinyGPSPlus::distanceBetween(gps.location.lat(), gps.location.lng(), des_LAT, des_LNG);
    double courseToDestination = TinyGPSPlus::courseTo(gps.location.lat(), gps.location.lng(), des_LAT, des_LNG);
    const char *directionToDestination = TinyGPSPlus::cardinal(courseToDestination);
    int courseChangeNeeded = (int)(360 + courseToDestination - gps.course.deg()) % 360;

    // debug
    Serial.print("DEBUG: Course2Dest: ");
    Serial.print(courseToDestination);
    Serial.print("  CurCourse: ");
    Serial.print(gps.course.deg());
    Serial.print("  Dir2Dest: ");
    Serial.print(directionToDestination);
    Serial.print("  RelCourse: ");
    Serial.print(courseChangeNeeded);
    Serial.print("  CurSpd: ");
    Serial.println(gps.speed.kmph());

    float l = gps.location.lat();
    Serial.println();
    Serial.print("Lat: "); Serial.print(l,6); Serial.print("  Lon: "); Serial.println(gps.location.lng());
    Serial.print("current Angle: "); Serial.println(atan2(gps.location.lat(), gps.location.lng())*180/M_PI);

    // Within 20 meters of destination?  We're here!
    if (distanceToDestination <= 20.0)
    {
      Serial.println("CONGRATULATIONS: You've arrived!");
      exit(1);
    }

    Serial.print("DISTANCE: ");
    Serial.print(distanceToDestination);
    Serial.println(" meters to go.");
    Serial.print("INSTRUCTION: ");

    // Standing still? Just indicate which direction to go.
    if (gps.speed.kmph() < 2.0)
    {
      Serial.print("Head ");
      Serial.print(directionToDestination);
      Serial.println(".");
      //return;
    }

    if (courseChangeNeeded >= 345 || courseChangeNeeded < 15)
      Serial.println("Keep on straight ahead!");
    else if (courseChangeNeeded >= 315 && courseChangeNeeded < 345)
      Serial.println("Veer slightly to the left.");
    else if (courseChangeNeeded >= 15 && courseChangeNeeded < 45)
      Serial.println("Veer slightly to the right.");
    else if (courseChangeNeeded >= 255 && courseChangeNeeded < 315)
      Serial.println("Turn to the left.");
    else if (courseChangeNeeded >= 45 && courseChangeNeeded < 105)
      Serial.println("Turn to the right.");
    else
      Serial.println("Turn completely around.");
  }
}

```

```arduino
    gps.encode(ss.read());

```

The encode() method returns a VERY important piece of information. You are foolish to discard that.

Speaking of foolish, you are assuming that the TinyGPS++ library has good data to compute a course from. That may NOT be a valid assumption. So, stop making it. Check!

---

<div class="post-metadata">

**Author:** ![srnet](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/srnet/32/238868_2.png) [@srnet](https://forum.arduino.cc/u/srnet)\
**Post date:** [March 29, 2017, 10:51am UTC](https://forum.arduino.cc/t/direction-course-from-tinygps-plus-library/448207/3 "2017-03-29T10:51:23Z")

</div>

And whilst you probably know what 'jumping around' means, how can the readers of the forum know ?

---

<div class="post-metadata">

**Author:** ![dev\_1](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/dev_1/32/215847_2.png) [@dev\_1](https://forum.arduino.cc/u/dev_1)\
**Post date:** [March 29, 2017, 2:46pm UTC](https://forum.arduino.cc/t/direction-course-from-tinygps-plus-library/448207/4 "2017-03-29T14:46:34Z")

</div>

IF by jumping around, you mean the GPS course (aka heading) is N, then S, then... various random directions, then yes, that's normal. Below 5kph, the course and speed are not accurate. The lat/lon is also wandering around your actual location, so you can't use that to compute speed, either.

BTW, all these GPS values could be "empty", or invalid. The GPS device will send an empty field when it doesn't know something. Like PaulS said, check the validity first.

My [NeoGPS](https://github.com/SlashDevin/NeoGPS) library has flags for all values so it's easy to check. It's also faster, smaller and more accurate, especially at smaller distances (\<1km). Here is a NeoGPS version of your sketch:

```cpp
#include <NeoSWSerial.h>
#include <NMEAGPS.h>

#define GPSBaud 9600
#define ConsoleBaud 115200

// The serial connection to the GPS device
//AltSoftSerial gpsPort; // pins 8 & 9 would be better!
#define RXPin 8
#define TXPin 7
NeoSWSerial gpsPort(RXPin, TXPin);

NMEAGPS gps;
uint8_t updates = 0; // used to count elapsed seconds

NeoGPS::Location_t des( 44.88285, -68.67253 ); // Orono, ME

void setup()
{
  Serial.begin(ConsoleBaud);
  gpsPort.begin(GPSBaud);

}

void loop()
{
  // Process characters from the GPS

  while (gps.available( gpsPort )) {
    gps_fix fix = gps.read();

    // Every 5 seconds, do an update.
    if (++updates >= 5) {
      updates = 0;
      Serial.println();

      // If we have a location, give instructions
      if (fix.valid.location) {

        // Establish our current status
        double distanceToDestination = fix.location.DistanceKm( des );
        double courseToDestination  = fix.location.BearingToDegrees( des );
        const __FlashStringHelper *directionToDestination =
                                        compassDir(courseToDestination);
        int courseChangeNeeded = (int)(360 + courseToDestination - fix.heading()) % 360;

        // debug
        Serial.print( F("DEBUG: Course2Dest: ") );
        Serial.print(courseToDestination);
        Serial.print( F("  CurCourse: ") );
        if (fix.valid.heading)
          Serial.print( fix.heading() );
        Serial.print( F("  Dir2Dest: ") );
        Serial.print(directionToDestination);
        Serial.print( F("  RelCourse: ") );
        Serial.print(courseChangeNeeded);
        Serial.print( F("Lat: ") );
        Serial.print( fix.latitude(), 6 );
        Serial.print( F("  Lon: ") );
        Serial.println( fix.longitude(), 6 );

        Serial.print( F("  CurSpd: ") );
        if (fix.valid.speed)
          Serial.print( fix.speed_kph() );
        Serial.println('\n');

        // ???  THIS ISN'T A THING
        //Serial.print( F("current Angle: ") );
        //Serial.println(atan2(gps.location.lat(), gps.location.lng())*180/M_PI);

        // Within 20 meters of destination?  We're here!
        if (distanceToDestination <= 20.0)
        {
          Serial.println( F("CONGRATULATIONS: You've arrived!") );
          exit(1);
        }

        Serial.print( F("DISTANCE: ") );
        Serial.print(distanceToDestination);
        Serial.println( F(" meters to go.") );
        Serial.print( F("INSTRUCTION: ") );

        // Standing still? Just indicate which direction to go.
        if (fix.speed_kph() < 5.0)
        {
          Serial.print( F("Head ") );
          Serial.print(directionToDestination);
          Serial.println( '.' );

        } else // suggest a course change
        if ((courseChangeNeeded >= 345) || (courseChangeNeeded < 15))
          Serial.println( F("Keep on straight ahead!") );
        else if ((courseChangeNeeded >= 315) && (courseChangeNeeded < 345))
          Serial.println( F("Veer slightly to the left.") );
        else if ((courseChangeNeeded >= 15) && (courseChangeNeeded < 45))
          Serial.println( F("Veer slightly to the right.") );
        else if ((courseChangeNeeded >= 255) && (courseChangeNeeded < 315))
          Serial.println( F("Turn to the left.") );
        else if ((courseChangeNeeded >= 45) && (courseChangeNeeded < 105))
          Serial.println( F("Turn to the right.") );
        else
          Serial.println( F("Turn completely around.") );
      } else {
        Serial.println( F("Waiting for GPS fix...") );
      }
    }
  }
}

//------------------------------------------------------------
//  This snippet is from NMEAaverage.  It keeps all the
//    compass direction strings in FLASH memory, saving RAM.

const char nCD  [] PROGMEM = "N";
const char nneCD[] PROGMEM = "NNE";
const char neCD [] PROGMEM = "NE";
const char eneCD[] PROGMEM = "ENE";
const char eCD  [] PROGMEM = "E";
const char eseCD[] PROGMEM = "ESE";
const char seCD [] PROGMEM = "SE";
const char sseCD[] PROGMEM = "SSE";
const char sCD  [] PROGMEM = "S";
const char sswCD[] PROGMEM = "SSW";
const char swCD [] PROGMEM = "SW";
const char wswCD[] PROGMEM = "WSW";
const char wCD  [] PROGMEM = "W";
const char wnwCD[] PROGMEM = "WNW";
const char nwCD [] PROGMEM = "NW";
const char nnwCD[] PROGMEM = "NNW";

const char * const dirStrings[] PROGMEM =
  { nCD, nneCD, neCD, eneCD, eCD, eseCD, seCD, sseCD, 
    sCD, sswCD, swCD, wswCD, wCD, wnwCD, nwCD, nnwCD };

const __FlashStringHelper *compassDir( uint16_t bearing ) // degrees CW from N
{
  const int16_t directions    = sizeof(dirStrings)/sizeof(dirStrings[0]);
  const int16_t degreesPerDir = 360 / directions;
        int8_t  dir          = (bearing + degreesPerDir/2) / degreesPerDir;

  while (dir < 0)
    dir += directions;
  while (dir >= directions)
    dir -= directions;

  return (const __FlashStringHelper *) pgm_read_ptr( &dirStrings[dir] );

} // compassDir

```

The major change is using the 1-second GPS updates for the 5-second interval timer. After 5 GPS updates (fixes) have been received, you know that 5 seconds have elapsed. Although it's not very important for a 5-second interval, you should be aware that the Arduino `millis()` will drift against the GPS clock. Sometimes 5000ms will 4 GPS updates, 6 updates, or even 4.5 updates (some new data, some old data).

Also notice that it uses my [NeoSWSerial](https://github.com/SlashDevin/NeoSWSerial) instead of SoftwareSerial. SoftwareSerial is very inefficient, because it disables interrupts for long periods of time. It will use about 95% of the CPU time, just waiting. This can interfere with other parts of your sketch or with other libraries.

AltSoftSerial is the absolute best choice for a second serial port, but you have to connect the GPS Tx/Rx to specific Arduino pins (e.g., 8/9 on an UNO). Strongly recommended!

Other changes:

- The F macro around string constants is used to save RAM.
- The compass direction strings are stored in FLASH, also saving RAM.
- All GPS fields are checked for validity before being used.
- If the location is not valid, it just displays "Waiting for GPS fix..."

The original sketch uses 11540 bytes of program space and 892 bytes of RAM.  
With NeoGPS/NeoSWSerial it uses 13010 bytes of program space and 408 bytes of RAM. NeoGPS saved about 100 bytes of RAM, and putting the strings in FLASH saved about 400 bytes of RAM.

If you want to try it, NeoGPS is available from the Arduino IDE Library Manager, under the menu **Sketch -\> Include Library -\> Manage Libraries**. Be sure to get v4.1.5, or download from github directly. Download NeoSWSerial from the link above.

Cheers,  
/dev

---

<div class="post-metadata">

**Author:** ![loyal979](https://avatars.discourse-cdn.com/v4/letter/l/b782af/32.png) [@loyal979](https://forum.arduino.cc/u/loyal979)\
**Post date:** [March 29, 2017, 11:31pm UTC](https://forum.arduino.cc/t/direction-course-from-tinygps-plus-library/448207/5 "2017-03-29T23:31:20Z")

</div>

> /dev:  
> IF by jumping around, you mean the GPS course (aka heading) is N, then S, then... various random directions, then yes, that's normal. Below 5kph, the course and speed are not accurate. The lat/lon is also wandering around your actual location, so you can't use that to compute speed, either.
> 
> BTW, all these GPS values could be "empty", or invalid. The GPS device will send an empty field when it doesn't know something. Like PaulS said, check the validity first.
> 
> My [NeoGPS](https://github.com/SlashDevin/NeoGPS) library has flags for all values so it's easy to check. It's also faster, smaller and more accurate, especially at smaller distances (\<1km). Here is a NeoGPS version of your sketch:
> 
> ```arduino
> #include <NeoSWSerial.h>
> 
> ```

#include \<NMEAGPS.h\>

#define GPSBaud 9600  
#define ConsoleBaud 115200

// The serial connection to the GPS device  
//AltSoftSerial gpsPort; // pins 8 & 9 would be better!  
#define RXPin 8  
#define TXPin 7  
NeoSWSerial gpsPort(RXPin, TXPin);

NMEAGPS gps;  
uint8\_t updates = 0; // used to count elapsed seconds

NeoGPS::Location\_t des( 44.88285, -68.67253 ); // Orono, ME

void setup()  
{  
&nbsp; Serial.begin(ConsoleBaud);  
&nbsp; gpsPort.begin(GPSBaud);

}

void loop()  
{  
&nbsp; // Process characters from the GPS

while (gps.available( gpsPort )) {  
&nbsp; &nbsp; gps\_fix fix = gps.read();

// Every 5 seconds, do an update.  
&nbsp; &nbsp; if (++updates \>= 5) {  
&nbsp; &nbsp; &nbsp; updates = 0;  
&nbsp; &nbsp; &nbsp; Serial.println();

// If we have a location, give instructions  
&nbsp; &nbsp; &nbsp; if (fix.valid.location) {

// Establish our current status  
&nbsp; &nbsp; &nbsp; &nbsp; double distanceToDestination = fix.location.DistanceKm( des );  
&nbsp; &nbsp; &nbsp; &nbsp; double courseToDestination&nbsp; = fix.location.BearingToDegrees( des );  
&nbsp; &nbsp; &nbsp; &nbsp; const \_\_FlashStringHelper \*directionToDestination =  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; compassDir(courseToDestination);  
&nbsp; &nbsp; &nbsp; &nbsp; int courseChangeNeeded = (int)(360 + courseToDestination - fix.heading()) % 360;

// debug  
&nbsp; &nbsp; &nbsp; &nbsp; Serial.print( F("DEBUG: Course2Dest: ") );  
&nbsp; &nbsp; &nbsp; &nbsp; Serial.print(courseToDestination);  
&nbsp; &nbsp; &nbsp; &nbsp; Serial.print( F("&nbsp; CurCourse: ") );  
&nbsp; &nbsp; &nbsp; &nbsp; if (fix.valid.heading)  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Serial.print( fix.heading() );  
&nbsp; &nbsp; &nbsp; &nbsp; Serial.print( F("&nbsp; Dir2Dest: ") );  
&nbsp; &nbsp; &nbsp; &nbsp; Serial.print(directionToDestination);  
&nbsp; &nbsp; &nbsp; &nbsp; Serial.print( F("&nbsp; RelCourse: ") );  
&nbsp; &nbsp; &nbsp; &nbsp; Serial.print(courseChangeNeeded);  
&nbsp; &nbsp; &nbsp; &nbsp; Serial.print( F("Lat: ") );  
&nbsp; &nbsp; &nbsp; &nbsp; Serial.print( fix.latitude(), 6 );  
&nbsp; &nbsp; &nbsp; &nbsp; Serial.print( F("&nbsp; Lon: ") );  
&nbsp; &nbsp; &nbsp; &nbsp; Serial.println( fix.longitude(), 6 );

Serial.print( F("&nbsp; CurSpd: ") );  
&nbsp; &nbsp; &nbsp; &nbsp; if (fix.valid.speed)  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Serial.print( fix.speed\_kph() );  
&nbsp; &nbsp; &nbsp; &nbsp; Serial.println('\n');

// ???&nbsp; THIS ISN'T A THING  
&nbsp; &nbsp; &nbsp; &nbsp; [//Serial.print](https://Serial.print)( F("current Angle: ") );  
&nbsp; &nbsp; &nbsp; &nbsp; [//Serial.println](https://Serial.println)(atan2(gps.location.lat(), gps.location.lng())\*180/M\_PI);

// Within 20 meters of destination?&nbsp; We're here!  
&nbsp; &nbsp; &nbsp; &nbsp; if (distanceToDestination \<= 20.0)  
&nbsp; &nbsp; &nbsp; &nbsp; {  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Serial.println( F("CONGRATULATIONS: You've arrived!") );  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; exit(1);  
&nbsp; &nbsp; &nbsp; &nbsp; }

Serial.print( F("DISTANCE: ") );  
&nbsp; &nbsp; &nbsp; &nbsp; Serial.print(distanceToDestination);  
&nbsp; &nbsp; &nbsp; &nbsp; Serial.println( F(" meters to go.") );  
&nbsp; &nbsp; &nbsp; &nbsp; Serial.print( F("INSTRUCTION: ") );

// Standing still? Just indicate which direction to go.  
&nbsp; &nbsp; &nbsp; &nbsp; if (fix.speed\_kph() \< 5.0)  
&nbsp; &nbsp; &nbsp; &nbsp; {  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Serial.print( F("Head ") );  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Serial.print(directionToDestination);  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Serial.println( '.' );

} else // suggest a course change  
&nbsp; &nbsp; &nbsp; &nbsp; if ((courseChangeNeeded \>= 345) || (courseChangeNeeded \< 15))  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Serial.println( F("Keep on straight ahead!") );  
&nbsp; &nbsp; &nbsp; &nbsp; else if ((courseChangeNeeded \>= 315) && (courseChangeNeeded \< 345))  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Serial.println( F("Veer slightly to the left.") );  
&nbsp; &nbsp; &nbsp; &nbsp; else if ((courseChangeNeeded \>= 15) && (courseChangeNeeded \< 45))  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Serial.println( F("Veer slightly to the right.") );  
&nbsp; &nbsp; &nbsp; &nbsp; else if ((courseChangeNeeded \>= 255) && (courseChangeNeeded \< 315))  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Serial.println( F("Turn to the left.") );  
&nbsp; &nbsp; &nbsp; &nbsp; else if ((courseChangeNeeded \>= 45) && (courseChangeNeeded \< 105))  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Serial.println( F("Turn to the right.") );  
&nbsp; &nbsp; &nbsp; &nbsp; else  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Serial.println( F("Turn completely around.") );  
&nbsp; &nbsp; &nbsp; } else {  
&nbsp; &nbsp; &nbsp; &nbsp; Serial.println( F("Waiting for GPS fix...") );  
&nbsp; &nbsp; &nbsp; }  
&nbsp; &nbsp; }  
&nbsp; }  
}

//------------------------------------------------------------  
//&nbsp; This snippet is from NMEAaverage.&nbsp; It keeps all the  
//&nbsp; &nbsp; compass direction strings in FLASH memory, saving RAM.

const char nCD&nbsp; [] PROGMEM = "N";  
const char nneCD[] PROGMEM = "NNE";  
const char neCD [] PROGMEM = "NE";  
const char eneCD[] PROGMEM = "ENE";  
const char eCD&nbsp; [] PROGMEM = "E";  
const char eseCD[] PROGMEM = "ESE";  
const char seCD [] PROGMEM = "SE";  
const char sseCD[] PROGMEM = "SSE";  
const char sCD&nbsp; [] PROGMEM = "S";  
const char sswCD[] PROGMEM = "SSW";  
const char swCD [] PROGMEM = "SW";  
const char wswCD[] PROGMEM = "WSW";  
const char wCD&nbsp; [] PROGMEM = "W";  
const char wnwCD[] PROGMEM = "WNW";  
const char nwCD [] PROGMEM = "NW";  
const char nnwCD[] PROGMEM = "NNW";

const char \* const dirStrings[] PROGMEM =  
&nbsp; { nCD, nneCD, neCD, eneCD, eCD, eseCD, seCD, sseCD,  
&nbsp; &nbsp; sCD, sswCD, swCD, wswCD, wCD, wnwCD, nwCD, nnwCD };

const \_\_FlashStringHelper \*compassDir( uint16\_t bearing ) // degrees CW from N  
{  
&nbsp; const int16\_t directions&nbsp; &nbsp; = sizeof(dirStrings)/sizeof(dirStrings[0]);  
&nbsp; const int16\_t degreesPerDir = 360 / directions;  
&nbsp; &nbsp; &nbsp; &nbsp; int8\_t&nbsp; dir&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = (bearing + degreesPerDir/2) / degreesPerDir;

while (dir \< 0)  
&nbsp; &nbsp; dir += directions;  
&nbsp; while (dir \>= directions)  
&nbsp; &nbsp; dir -= directions;

return (const \_\_FlashStringHelper \*) pgm\_read\_ptr( &dirStrings[dir] );

} // compassDir

> ```arduino
> 
> The major change is using the 1-second GPS updates for the 5-second interval timer. After 5 GPS updates (fixes) have been received, you know that 5 seconds have elapsed. Although it's not very important for a 5-second interval, you should be aware that the Arduino `millis()` will drift against the GPS clock. Sometimes 5000ms will 4 GPS updates, 6 updates, or even 4.5 updates (some new data, some old data).
> 
> Also notice that it uses my [NeoSWSerial](https://github.com/SlashDevin/NeoSWSerial) instead of SoftwareSerial. SoftwareSerial is very inefficient, because it disables interrupts for long periods of time. It will use about 95% of the CPU time, just waiting. This can interfere with other parts of your sketch or with other libraries.
> 
> AltSoftSerial is the absolute best choice for a second serial port, but you have to connect the GPS Tx/Rx to specific Arduino pins (e.g., 8/9 on an UNO). Strongly recommended!
> 
> Other changes:
> 
> * The F macro around string constants is used to save RAM.
> * The compass direction strings are stored in FLASH, also saving RAM.
> * All GPS fields are checked for validity before being used.
> * If the location is not valid, it just displays "Waiting for GPS fix..."
> 
> The original sketch uses 11540 bytes of program space and 892 bytes of RAM.
> With NeoGPS/NeoSWSerial it uses 13010 bytes of program space and 408 bytes of RAM. NeoGPS saved about 100 bytes of RAM, and putting the strings in FLASH saved about 400 bytes of RAM.
> 
> If you want to try it, NeoGPS is available from the Arduino IDE Library Manager, under the menu **Sketch -> Include Library -> Manage Libraries**. Be sure to get v4.1.5, or download from github directly. Download NeoSWSerial from the link above.
> 
> Cheers,
> /dev
> 
> ```

Thanks /dev, I don't think your could will work with me because Im using adafruit ultimate gps+logging shield. Or, is there a way to use your code with adafruit gps?

---

<div class="post-metadata">

**Author:** ![dev\_1](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/dev_1/32/215847_2.png) [@dev\_1](https://forum.arduino.cc/u/dev_1)\
**Post date:** [March 30, 2017, 12:43pm UTC](https://forum.arduino.cc/t/direction-course-from-tinygps-plus-library/448207/6 "2017-03-30T12:43:31Z")

</div>

> is there a way to use your code with adafruit gps?

Yes, NeoGPS supports all GPS devices that output the standard set of NMEA sentences, like RMC and GGA. Many people have used NeoGPS with the Adafruit GPS devices. It will not void your warranty. 😉

**If you are using the logging functions:** There is one peciliarity of that shield: it has an SD card reader and a MTK3329 GPS device, and there are actually two ways to log information with that shield:

**1)** Parse GPS information with a library (Adafruit\_GPS or NeoGPS) and write whatever you want to the SD card, using an Arduino library for the SD card. To retrive the logged data, just remove the SD card an open the SD file in your computer.

**\*** The Adafruit example just writes the raw NMEA data to the SD card. There are many NMEA utilities for using the raw data.

**\*** The [NeoGPS example](https://github.com/SlashDevin/NeoGPS/blob/master/examples/NMEASDlog/NMEASDlog.ino) will write _parsed_ values (e.g., lat/lon) in a CSV file format, not the raw NMEA characters. You can configure NeoGPS to enable or disable the GPS fields you want, and you can modify the sketch to change the format of the file. It is easy to import a CSV file into a spreadsheet, and there are many utilities that take CSV files of "Geo" information.

**2)** Send a command to the MTK3329 GPS device that enables its internal non-volatile memory. Adafruit does not recommend this technique, as there is limited space, a different sketch is required to retrieve the information from the GPS device (not the SD card), and you do not have any control over the format of the saved information. A NeoGPS sketch could start and stop the logging function, but you would still have to use a different sketch to retrieve the information from the GPS device.

Adafruit recommends the first approach, as do I. I also recommend saving parsed data, not raw. The log file will be 5 to 10 times smaller. I don't know your application, but this could affect battery life or system responsiveness.

**If you are not using the logging functions** , I would not suggest using the Adafruit library: it does not validate the checksum on GPS data. When combined with a software serial connection, it could produce invalid locations.

Cheers,  
/dev

---

<div class="post-metadata">

**Author:** ![jurs](https://avatars.discourse-cdn.com/v4/letter/j/43a26b/32.png) [@jurs](https://forum.arduino.cc/u/jurs)\
**Post date:** [March 30, 2017, 1:57pm UTC](https://forum.arduino.cc/t/direction-course-from-tinygps-plus-library/448207/7 "2017-03-30T13:57:31Z")

</div>

> loyal979:  
> Hi all,
> 
> Im trying to calculate or printing the current course in deg. by using the function gps.course.deg() from tinygps library to give me my current course. but the course is jumping around and Im not sure how the course is being calculated.

The library you mentioned is available with full source code, so if you are interested in how the calculation is done, look up the source code!

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [May 5, 2021, 10:26pm UTC](https://forum.arduino.cc/t/direction-course-from-tinygps-plus-library/448207/8 "2021-05-05T22:26:16Z")

</div>

Closed on May 5, 2021, 10:26pm UTC


