You can try this sketch.
Hook up the GPS module to the hardware TX/RX (USART0) of your Arduino and connect a serial adapter (RX line) to USART1, or to pin 2 if no second USART is present on your board.
The Arduino led will turn on when a valid GPS fix is received and turn off if it fails. You can test that by putting your hand around the GPS antenna and in a few seconds the led should turn off.
/* Connect GPS to USART0 (Hardware serial 0)
* Connect serial adapter to Hardware Serial 1 or to pin 2 if no HW Serial1 is present on your MCU
*/
#ifndef HAVE_HWSERIAL1
#include <SoftwareSerial.h>
SoftwareSerial Serial1(3, 2); // RX, TX
#endif
//format hex command strings for sending to UBLOX
const char airborne[] = {0xb5, 0x62, 0x06, 0x24, 0x24, 0x00, 0xff, 0xff, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10, 0x27,
0x00, 0x00, 0x05, 0x00, 0xfa, 0x00, 0xfa, 0x00, 0x64, 0x00, 0x2c, 0x01, 0x00, 0x3c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x0b, 0xb5, 0x62, 0x06, 0x24,
0x00, 0x00, 0x2a, 0x84
};
const char hnr[] = {0xB5, 0x62, 0x06, 0x5C, 0x04, 0x00, 0x05, 0x00, 0x00, 0x00, 0x6B, 0xE0}; // high nav rate to 5Hz
const char rate[] = {0xB5, 0x62, 0x06, 0x08, 0x06, 0x00, 0xC8, 0x00, 0x01, 0x00, 0x01, 0x00, 0xDE, 0x6A}; // output at 5 Hz
const char pvt[] = {0xb5, 0x62, 0x06, 0x01, 0x03, 0x00, 0x01, 0x07, 0x01, 0x13, 0x51}; // activate PVT sentence
#define GPS_INFO_BUFFER_SIZE 100 // enough for the strings (PVT is 100 long)
byte GPS_info_buffer[GPS_INFO_BUFFER_SIZE];
byte string_length = 98; //PVT is 100 Initialize with longest string.
unsigned int received_char;
int i = 0; // counter
bool message_started = false;
long velN; // North vector of 3D speed
long velE; // East vector of 3D speed
long velD; // Down vector of 3D speed
unsigned long ThreeD_spd_kts; //3D speed in knots
long longitude ;//longitude
long latitude ;//latitude
long height_above_sea_level;//height above main sea level
unsigned long ground_speed ;
unsigned long heading;
//CHECKSUM CALCULATION VARIABLE
unsigned char CK_A = 0;
unsigned char CK_B = 0;
byte fixok = 0; // flag to indicate a valid GPS fix was received.
byte fixcount = 0; // count how many OK GPS fixes we have in a row.
void setup() {
Serial1.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite (LED_BUILTIN, HIGH); // signal led on, to test
delay(2000); // wait for GPS to boot (and Softwareserial also needs some time.)
Serial1.println(F("printing is up and running."));
Serial.begin(9600);
delay(100);
Serial.println(F("$PUBX,40,RMC,0,0,0,0*47")); //RMC OFF
delay(100);
Serial.println(F("$PUBX,40,VTG,0,0,0,0*5E")); //VTG OFF
delay(100);
Serial.println(F("$PUBX,40,GGA,0,0,0,0*5A")); //GGA OFF
delay(100);
Serial.println(F("$PUBX,40,GSA,0,0,0,0*4E")); //GSA OFF
delay(100);
Serial.println(F("$PUBX,40,GSV,0,0,0,0*59")); //GSV OFF
delay(100);
Serial.println(F("$PUBX,40,GLL,0,0,0,0*5C")); //GLL OFF
delay(100);
// Serial.write(airborne, sizeof(airborne)); //set GPS mode to airborne < 4g
// delay(100);
// Serial.write(hnr, sizeof(hnr)); //set GPS update rate to 4Hz (1st string)
// delay(100);
// Serial.write(rate, sizeof(rate)); //set GPS update rate to 4Hz (2nd string)
// delay(100);
Serial.write(pvt, sizeof(pvt)); // PVT Navigation Position Velocity Time Solution message ON
delay(100);
digitalWrite (13, LOW); // signal led off, end setup
} // end setup
void loop() {
if (Serial.available()) { // If GPS data is available
byte GPS_info_char = Serial.read(); // Read it and store as HEX char
if (GPS_info_char == 0xb5) { // ublox B5 record found
message_started = true;
received_char = 0;
} // end ublox B5 record found
else if (message_started == true) { // the message is already started and I got a new character
if (received_char < string_length) { // buffer not full
GPS_info_buffer[received_char] = GPS_info_char;
if (GPS_info_buffer[2] == 0x07) string_length = 98; //PVT lenght is 84 + 6
received_char++;
} // end buffer not full
else { // final character received
GPS_info_buffer[received_char] = GPS_info_char;
UBX_calculate_checksum(GPS_info_buffer, 1, (string_length - 2)); // calculates checksum
if (string_length == 98) { // PVT string received
if ((CK_A == GPS_info_buffer[string_length - 1] && CK_B == GPS_info_buffer[string_length]) && (( GPS_info_buffer[21 + 5] & B00000001) && ( GPS_info_buffer[20 + 5] == 0x03))) { // checksum ok and fix ok
// confirm (received and calculated checksums are the same) && (fix status flag = 1 AND a 3Dfix)
if (fixcount < 10) fixcount ++; // count how many valid fixes
digitalWrite (LED_BUILTIN, HIGH); // signal led on, we have a valid GPS fix
// convert the GPS buffer array bytes 24,23,22,21 into one "unsigned long" (4 byte) field
velN = (long)GPS_info_buffer[51 + 5] << 24;
velN += (long)GPS_info_buffer[50 + 5] << 16;
velN += (long)GPS_info_buffer[49 + 5] << 8;
velN += (long)GPS_info_buffer[48 + 5];
velE = (long)GPS_info_buffer[55 + 5] << 24;
velE += (long)GPS_info_buffer[54 + 5] << 16;
velE += (long)GPS_info_buffer[53 + 5] << 8;
velE += (long)GPS_info_buffer[52 + 5];
velD = (long)GPS_info_buffer[59 + 5] << 24;
velD += (long)GPS_info_buffer[58 + 5] << 16;
velD += (long)GPS_info_buffer[57 + 5] << 8;
velD += (long)GPS_info_buffer[56 + 5];
// for high-G model aircraft wait for some valid GPS fixes to dampen 3D speed errors after sharp turns
if (fixcount > 8) ThreeD_spd_kts = (((float)(sqrt(sq(velN) + sq(velE) + sq(velD))) * 1.94381) / 100); // calculate 3D speed in Knots from speedvectors
else ThreeD_spd_kts = 0;
ground_speed = (long)GPS_info_buffer[63 + 5] << 24;
ground_speed += (long)GPS_info_buffer[62 + 5] << 16;
ground_speed += (long)GPS_info_buffer[61 + 5] << 8;
ground_speed += (long)GPS_info_buffer[60 + 5];
ground_speed = (((float)ground_speed * 1.94381)) ;
heading = (long)GPS_info_buffer[67 + 5] << 24;
heading += (long)GPS_info_buffer[66 + 5] << 16;
heading += (long)GPS_info_buffer[65 + 5] << 8;
heading += (long)GPS_info_buffer[64 + 5];
heading = heading / 1000;
longitude = (long)GPS_info_buffer[27 + 5] << 24;
longitude += (long)GPS_info_buffer[26 + 5] << 16;
longitude += (long)GPS_info_buffer[25 + 5] << 8;
longitude += (long)GPS_info_buffer[24 + 5];
latitude = (long)GPS_info_buffer[31 + 5] << 24;
latitude += (long)GPS_info_buffer[30 + 5] << 16;
latitude += (long)GPS_info_buffer[29 + 5] << 8;
latitude += (long)GPS_info_buffer[28 + 5];
height_above_sea_level = (long)GPS_info_buffer[39 + 5] << 24;
height_above_sea_level += (long)GPS_info_buffer[38 + 5] << 16;
height_above_sea_level += (long)GPS_info_buffer[37 + 5] << 8;
height_above_sea_level += (long)GPS_info_buffer[36 + 5];
height_above_sea_level = (height_above_sea_level / 10);
}// end parse PVT sentence
else {// when checksum error or no fix set values to zero
fixcount = 0;
digitalWrite (LED_BUILTIN, LOW); // signal led off, we have no valid GPS fix
ThreeD_spd_kts = 0;
ground_speed = 0;
heading = 0;
longitude = 0;
latitude = 0;
height_above_sea_level = 0;
}// end when checksum or fix fails
//print values
Serial1.print("Latitude: ");
Serial1.print(float(latitude) / 10000000, 7);
Serial1.print("\tLongitude: ");
Serial1.print(float(longitude) / 10000000, 7);
Serial1.print("\tHeight above sealevel: ");
Serial1.print(height_above_sea_level);
Serial1.print("\tGround Speed: ");
Serial1.print(ground_speed);
Serial1.print("\t3D Speed: ");
Serial1.print(ThreeD_spd_kts);
// Serial1.print("\tHeading: ");
// Serial1.print(heading);
Serial1.println();
}
message_started = false; // ready for the new message
} // end final character received
} // end the message is already started and I got a new character
} // end If GPS data is available
} // end loop
// CALCULATES THE UBX CHECKSUM OF A CHAR ARRAY
void UBX_calculate_checksum(uint8_t* array, unsigned int array_start, unsigned int array_length) {
CK_A = 0;
CK_B = 0;
unsigned int i;
for (i = 0; i < array_length; i++) {
CK_A = CK_A + array[array_start + i];
CK_B = CK_B + CK_A;
}
}