SoftwareSerial disables interrupts for long periods of time, so the servo probably won't like that, and the Adafruit_GPS timer interrupt won't help.
The Arduino PWM-capable pins (e.g., pin 10) can control a servo without interrupts. I hope you are using the Servo library in a way that allows the hardware to generates all the pulses, not with a timer interrupt and software (bit-banging). I don't see any Servo code besides the attach call. You might need to set the min and max pulse width limits (read this).
**To replace SoftwareSerial: ** The best software serial library is AltSoftSerial, but it requires two specific pins (8 & 9 on an UNO). It also prevents using PWM on pin 10. If you could put your servo on a different PWM pin, you could use AltSoftSerial. Connect the GPS TX to pin 8 and GPS RX to pin 9. Since you have a shield, you'd have to do some soldering to make this connection.
The next best library is my NeoSWSerial. Use any two pins (e.g., 8 & 7) for a GPS @ 9600, 19200 or 38400. If the servo library disables interrupts for a long time (I don't think it does), it could also interfere with NeoSWSerial.
Here's a NeoGPS version of your sketch:
#include <NMEAGPS.h>
#include <NeoSWSerial.h>
NeoSWSerial gpsPort(8, 7);
NMEAGPS GPS;
NeoGPS::Location_t waypoints[] =
{
{ 401433180, -830602320 },
{ 401428540, -830597870 },
{ 401424500, -830601600 },
{ 401427750, -830606690 },
{ 401423060, -830607000 }
};
int currentWaypoint = 0;
const int MAX_WAYPOINT = sizeof(waypoints)/sizeof(waypoints[0]);
float waypointDistance = 0.0; // km
float headingdegree = 0.0;
void setup()
{
Serial.begin(115200);
Serial.println( F("GPS heading each waypoint!") ); // F macro saves RAM
gpsPort.begin(9600);
GPS.send_P( &gpsPort, F("PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0") ); // RMC only
GPS.send_P( &gpsPort, F("PMTK220,1000") ); // 1 Hz update rate
}
void loop() {
// Process GPS characters
if (GPS.available( gpsPort )) {
// A new fix structure is finally ready, get it.
gps_fix fix = GPS.read();
if (fix.valid.location) {
waypointDistance = fix.location.DistanceKm( waypoints[ currentWaypoint ] );
headingdegree = fix.location.BearingToDegrees( waypoints[ currentWaypoint ] );
Serial.print( F("Current location: ") );
Serial.print( fix.latitude(), 6 );
Serial.print( F(", ") );
Serial.println( fix.longitude(), 6 );
Serial.print( F("Current Waypoint: ") );
Serial.print( waypoints[ currentWaypoint ].latF(), 6 );
Serial.print( F(", ") );
Serial.println( waypoints[ currentWaypoint ].lonF(), 6 );
Serial.println( headingdegree );
Serial.println( waypointDistance );
//if waypointDistance< 5; currentWaypoint++
// Step to the next waypoint when user types something
if (Serial.available()) {
Serial.read();
currentWaypoint ++;
if (currentWaypoint >= MAX_WAYPOINT)
currentWaypoint = 0; // start over...
}
}
}
}
You can see that it's much shorter and easier to read. It also shows the C++ needed to declare and use an array of NeoGPS::Location_t elements. The major difference is the loop structure. In the NeoGPS version, it processes GPS characters until a complete fix is ready. That happens once per second.
When a new fix is finally ready, it calculates the distance and bearing and prints a few things. Notice how there are no delays that keep other things from working. The rest of the time, loop just runs over and over, checking if gps.available().
Your original sketch uses 12140 bytes of program space and 997 bytes of RAM (almost half of it!).
The NeoGPS version uses 11076 bytes of program space and 395 bytes of RAM.
Cheers,
/dev