You are printing too much. You should probably get the compass heading only when you receive a GPS update. Then you will print the heading just once per second. Right now, your sketch prints every time through loop. This prevents it from getting all the GPS characters.
Here's a NeoGPS version of your sketch:
#include <NMEAGPS.h>
#include <Wire.h>
#include <HMC5883L_Simple.h>
#define SERIAL_BAUD 115200
#define GPS_BAUD 9600
#define N_FLOATS 4
HMC5883L_Simple Compass;
NMEAGPS M8_Gps;
NeoGPS::Location_t previousLocation;
bool havePrevious = false;
// Altitude - Latitude - Longitude - N Satellites
float gpsArray[N_FLOATS] = {0, 0, 0, 0};
void setup() {
Serial.begin(SERIAL_BAUD);
Serial1.begin(GPS_BAUD);
Wire.begin();
//Colombo - Magnetic declination: -2° 10'
Compass.SetDeclination(-2, 10, 'W');
Compass.SetSamplingMode(COMPASS_SINGLE);
Compass.SetScale(COMPASS_SCALE_130);
Compass.SetOrientation(COMPASS_HORIZONTAL_X_NORTH);
//digitalWrite(SDA, LOW);
//digitalWrite(SDL, LOW);
}
const char *g[5] = { "alt", "lat", "lon", "sat" };
void loop() {
if (M8_Gps.available( Serial1 )) {
gps_fix fix = M8_Gps.read();
gpsArray[0] = fix.altitude();
gpsArray[1] = fix.latitude();
gpsArray[2] = fix.longitude();
gpsArray[3] = fix.satellites;
float heading = Compass.GetHeadingDegrees(); //**********
Serial.print( F("Heading from compass: \t") ); // F macro saves RAM
Serial.println( heading );
Serial.print( F("Heading from GPS: \t") );
Serial.println( fix.heading() );
if (havePrevious) {
Serial.print( F("Heading from previous location: \t") );
Serial.println( previousLocation.BearingToDegrees( fix.location ) );
} else
havePrevious = true;
previousLocation = fix.location;
//
for(byte i = 0; i < N_FLOATS; i++) {
Serial.print( g[i] ); Serial.print(' ');
Serial.print( gpsArray[i], 6 ); Serial.print(' ');
}
Serial.println();
}
}
Notes:
* You don't need to use the [u]S[/u]tring
class for the labels. You can just use char
arrays, also called C strings.
* loop
simply asks the GPS object if it has a new update (i.e., a fix structure). When a new fix is available, it reads it and uses the values.
* NeoGPS is smaller, faster and more accurate than all other libraries. You can configure it to parse only the pieces you use (lat, lon, and alt in your case). All other pieces will be quickly skipped, saving even more program space and RAM
Your original sketch uses 14266 bytes of program space and 972 bytes of RAM.
The NeoGPS version uses 11204 bytes of program space and 654 bytes of RAM, a significant savings.
If you want to try it, it is also available from the Arduino IDE Library Manager, under the menu Sketch -> Include Library -> Manage Libraries.
Cheers,
/dev
Edited to add printing of GPS heading and NeoGPS calculation of heading from the previous location. The NeoGPS calculation is much more accurate than other libraries.