You have to keep up with the speed that the GPS is outputting. It's not waiting for you to ask for something. And given the fact you want to increase baudrate, that's only getting worse.
The Serial.read() function in Arduino does that already. It is triggered by the USARTn_RX interrupt vector (USARTn Rx Complete) to take a character from the two byte UART rx buffer and put it in the serial read buffer, waiting for your serial.read() to pick it up.
So what you need to do is read ALL available characters from the serial.read()buffer, so that the serial.read() buffer is empty. Once it is empty, you have time to do something else, that takes 20 milliseconds. Because while doing that, the Arduino serial function will fill the serial.read buffer in the background, via the USARTn_RX interrupt
Just by adding one "else" statement you can accomplish that
// rest of programming here
else { // there are no characters to be processed in the serial.read buffer
delay(250); // so there is time to do something else
SerialMonitor.println("delaying"); //
}
} // end loop
In this example I can afford a 250 millisecond delay and it contines to run. This is with a GPS baudrate of 9600. With your higher baudrate the delay you can afford will be less, but that is easy to try.
/******************************************************************************
This example uses SoftwareSerial to communicate with the GPS module on
pins 8 and 9. SoftwareSerial should work on most Arduinos, but it's a
necessity on Arduino Mega's, Arduino Uno's, RedBoard's and any other Arduino
based around an ATmega328P.
After uploading the code, open your serial monitor, set it to 9600 baud, and
watch the GPS module's NMEA strings begin to flow by. See if you can pick
out the latitude and longitude.
******************************************************************************/
#
#define GPS_BAUD_RATE 9600 // The GPS Shield module defaults to 9600 baud
// Create a SoftwareSerial object called gps:
// We'll also define a more descriptive moniker for the Serial Monitor port.
// This is the hardware serial port on pins 0/1.
#define gpsPort Serial
#define SerialMonitor Serial1
//format hex command strings for sending to UBLOX
const char velned[] = {0xb5, 0x62, 0x06, 0x01, 0x03, 0x00, 0x01, 0x12, 0x01, 0x1e, 0x67};
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 rate_a[] = {0xb5, 0x62, 0x06, 0x08, 0x06, 0x00, 0xfa, 0x00, 0x01, 0x00, 0x01, 0x00, 0x10, 0x96};
const char rate_b[] = {0xb5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x0e, 0x30};
#define GPS_INFO_BUFFER_SIZE 50
//char GPS_info_char;
byte GPS_info_buffer[GPS_INFO_BUFFER_SIZE];
unsigned int received_char;
int i = 0; // counter
bool message_started = false;
unsigned long ms_time_week; //GPS millicecond Time of Week
unsigned long velocity_3d; // speed in centimeter / second
float spd_kph; //speed in kilometers per hour
unsigned long velocity_accuracy; // in centimeter / second
//CHECKSUM CALCULATION VARIABLE
unsigned char CK_A = 0;
unsigned char CK_B = 0;
void setup()
{
delay(1000);
gpsPort.begin(GPS_BAUD_RATE);
SerialMonitor.begin(9600);
SerialMonitor.println("start of setup");
delay(100);
gpsPort.println(F("$PUBX,40,RMC,0,0,0,0*47")); //RMC OFF
delay(100);
gpsPort.println(F("$PUBX,40,VTG,0,0,0,0*5E")); //VTG OFF
delay(100);
gpsPort.println(F("$PUBX,40,GGA,0,0,0,0*5A")); //CGA OFF
delay(100);
gpsPort.println(F("$PUBX,40,GSA,0,0,0,0*4E")); //GSA OFF
delay(100);
gpsPort.println(F("$PUBX,40,GSV,0,0,0,0*59")); //GSV OFF
delay(100);
gpsPort.println(F("$PUBX,40,GLL,0,0,0,0*5C")); //GLL OFF
delay(100);
gpsPort.write(airborne, sizeof(airborne)); //set GPS mode to airborne < 4g
delay(100);
gpsPort.write(rate_a, sizeof(rate_a)); //set GPS update rate to 4Hz
delay(100);
gpsPort.write(rate_b, sizeof(rate_b)); //set GPS update rate to 4Hz
delay(100);
gpsPort.write(velned, sizeof(velned)); // VELNED (VELocity, North, East, Down) message ON
}
void loop()
{ //start loop
if (gpsPort.available()) { // If GPS data is available
byte *GPS_info_char = gpsPort.read(); // Read it and store as HEX char
if (GPS_info_char == 0xb5) { // ublox B5 gevonden
//SerialMonitor.println("UBLUX b5 gevonden");
message_started = true;
received_char = 0;
} // end ublox B5 gevonden
else if (message_started == true) { // the message is already started and I got a new character
if (received_char < 42) { // buffer not full
GPS_info_buffer[received_char] = GPS_info_char;
received_char++;
} else { // final character received
GPS_info_buffer[received_char] = GPS_info_char;
// for (i = 0; i <= received_char; i++) {
// SerialMonitor.print(GPS_info_buffer[i], HEX); // writes the buffer to the PC once it has been completely received
// SerialMonitor.print("."); // writes dot inbetween characters
// }
// SerialMonitor.print("...checksum received..."); // the last 2 received characters are the checksum
// SerialMonitor.print(GPS_info_buffer[41],HEX);
// SerialMonitor.print("."); // writes dot inbetween lines
// SerialMonitor.print(GPS_info_buffer[42],HEX);
// SerialMonitor.print("."); // writes dot inbetween lines
UBX_calculate_checksum(GPS_info_buffer, 1, 40); // calculates checksum
// SerialMonitor.print("...calculated checksum..."); // calculated checksum from received characters
// SerialMonitor.print(CK_A,HEX);
// SerialMonitor.print("."); // writes dot inbetween lines
// SerialMonitor.print(CK_B,HEX);
// SerialMonitor.println("."); // writes dot inbetween lines
if (CK_A == GPS_info_buffer[41] && CK_B == GPS_info_buffer[42]) { // confirm received and calculated checksums are the same
// Serial.println("Checksum ok");
// convert the GPS buffer array bytes 8,7,6,5 into one "unsigned long" (4 byte) field
ms_time_week = (long)GPS_info_buffer[8] << 24;
ms_time_week += (long)GPS_info_buffer[7] << 16;
ms_time_week += (long)GPS_info_buffer[6] << 8;
ms_time_week += (long)GPS_info_buffer[5];
SerialMonitor.print(" Timestamp: ");
SerialMonitor.print(ms_time_week,DEC);
// convert the GPS buffer array bytes 24,23,22,21 into one "unsigned long" (4 byte) field
velocity_3d = (long)GPS_info_buffer[24] << 24;
velocity_3d += (long)GPS_info_buffer[23] << 16;
velocity_3d += (long)GPS_info_buffer[22] << 8;
velocity_3d += (long)GPS_info_buffer[21];
// SerialMonitor.print(" Velocity_3D: ");
// SerialMonitor.print(velocity_3d, DEC);
spd_kph = (((float)velocity_3d * 36)/ 1000);
SerialMonitor.print(" Km/h.. ");
SerialMonitor.print(spd_kph,2);
// convert the GPS buffer array bytes 36,35,34,33 into one "unsigned long" (4 byte) field
velocity_accuracy = (long)GPS_info_buffer[36] << 24;
velocity_accuracy += (long)GPS_info_buffer[35] << 16;
velocity_accuracy += (long)GPS_info_buffer[34] << 8;
velocity_accuracy += (long)GPS_info_buffer[33];
// SerialMonitor.print(" Velocity_accuracy: ");
// SerialMonitor.print(velocity_accuracy, DEC);
SerialMonitor.println();
}
else SerialMonitor.println("Checksum error");
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
// rest of programming here
else { // there are no characters to be processed in the serial.read buffer
delay(250); // so there is time to do something else
SerialMonitor.println("delaying"); //
}
} // 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;
}
}