Hello all,
I am working on a school project with a couple of my peers and I have a problem with the GPS data printing out improperly every loop when I integrate the code with their code. I believe it is all timing related but I am wondering if someone can help me or point me in the right direction to force the code to hold of in the main loop (or the GPS function) until the GPS data is read, parsed, formatted and printed out to the serial port once and properly. I've tried using a while loop but when I do, the code stays on the GPS function all the time. Please disregard all the millis() code, I wrote all those in to check timing on all the functions...
I believe I can use a while loop or a do-while loop but I am not sure how to implement this. Basically, I need the main loop to run and wait for a valid GPS sentence to be read, parsed, formatted and printed on the serial port when it reaches the serialGPS() function.
The GPS will print out GPS coordinates when the "if (strncmp(buffer, "$GPRMC",6) == 0)" condition is met. However, there are instances when I get invalid coordinates:
Lattitude: 111° 2' 32.87"
Longitude: 0° 0' 0.0"
Lattitude: 8° 12' 0.0"
Longitude: 0° 0' 0.0"
Lattitude: 0° 34' 1.22"
Longitude: 3° 22' 0.0"
Once I change the condition to "while (strncmp(buffer, "$GPRMC",6) == 0)" I get good results as listed below. However It stay in this infinite loop.
Lattitude: 32°N 21' 0.13"
Longitude: 111°W 2' 32.97"
Lattitude: 32°N 21' 0.13"
Longitude: 111°W 2' 32.97"
Lattitude: 32°N 21' 0.13"
Longitude: 111°W 2' 32.97"
Lattitude: 32°N 21' 0.13"
Longitude: 111°W 2' 32.97"
I've tried using a break; but it functions similarly as if I was using the if condition. I also used various baud rates and refresh rates on the GPS but I had not luck. Below is the code I am using with regards to the GPS and the main loop. Any help with this is greatly appreciated!
void loop()
{
start=millis();
systemInit();
finished=millis();
Serial.println("Finished");
elapsed=finished-start;
Serial.print(elapsed);
Serial.println(" milliseconds for System Initialization");
Serial.println();
delay(2000);
while(1)
{
start=millis();
function1();
function2();
function3();
function4();
serialGPScomm();
finished=millis();
Serial.print("Finisihed");
Serial.println();
elapsed=finished-start;
Serial.print(elapsed);
Serial.println(" milliseconds for Main Loop");
Serial.println();
}
}
void readline(void) {
start=millis();
char c;
buffidx = 0; // start at begninning
while (1) {
c=Serial1.read();
if (c == -1)
continue;
//Serial.print(c);
if (c == '\n')
continue;
if ((buffidx == BUFFERSIZE-1) || (c == '\r')) {
buffer[buffidx] = 0;
return;
}
buffer[buffidx++]= c;
}
}
uint32_t parsedecimal(char *str) {
uint32_t d = 0;
while (str[0] != 0) {
if ((str[0] > '9') || (str[0] < '0'))
return d;
d *= 10;
d += str[0] - '0';
str++;
}
return d;
finished=millis();
Serial.println("Finished");
elapsed=finished-start;
Serial.print(elapsed);
Serial.println(" milliseconds for readline() function");
}
void serialGPScomm()
{
start=millis();
uint32_t tmp;
readline();
//Check if $GPRMC sentence type
if (strncmp(buffer, "$GPRMC",6) == 0) {
//HHMMSS Time Stamp
parseptr = buffer+7;
tmp = parsedecimal(parseptr);
hour = tmp / 10000;
minute = (tmp / 100) % 100;
second = tmp % 100;
parseptr = strchr(parseptr, ',') + 1;
status = parseptr[0];
parseptr += 2;
//Acquire Latitude & Longitude data
//Latitude
latitude = parsedecimal(parseptr);
if (latitude != 0)
{
latitude *= 10000;
parseptr = strchr(parseptr, '.')+1;
latitude += parsedecimal(parseptr);
}
parseptr = strchr(parseptr, ',') + 1;
//Read Latitude N/S data
if (parseptr[0] != ',')
{
latdir = parseptr[0];
}
//Longitude
parseptr = strchr(parseptr, ',')+1;
longitude = parsedecimal(parseptr);
if (longitude != 0)
{
longitude *= 10000;
parseptr = strchr(parseptr, '.')+1;
longitude += parsedecimal(parseptr);
}
parseptr = strchr(parseptr, ',')+1;
//Read longitude E/W data
if (parseptr[0] != ',')
{
longdir = parseptr[0];
}
//Groundspeed
parseptr = strchr(parseptr, ',')+1;
groundspeed = parsedecimal(parseptr);
//Track angle
parseptr = strchr(parseptr, ',')+1;
trackangle = parsedecimal(parseptr);
//Date
parseptr = strchr(parseptr, ',')+1;
tmp = parsedecimal(parseptr);
date = tmp / 10000;
month = (tmp / 100) % 100;
year = tmp % 100;
//Output GPS information
// GPS data processed and formated for Display
Serial.print("\n\n");
Serial.print("\t");
Serial.print("Lattitude: \t");
Serial.print(latitude/1000000, DEC); Serial.print((char)176);
if (latdir == 'N')
{
Serial.print('N');
}
else if (latdir == 'S')
Serial.print('S');
Serial.print(' ');
Serial.print((latitude/10000)%100, DEC); Serial.print('\''); Serial.print(' ');
Serial.print((latitude%10000)*6/1000, DEC); Serial.print('.');
Serial.print(((latitude%10000)*6/10)%100, DEC); Serial.print('"'); Serial.print(',');
Serial.print("\n");
Serial.print("\t");
Serial.print("Longitude: \t");
Serial.print(longitude/1000000, DEC); Serial.print((char)176);
if (longdir == 'E')
{
Serial.print('E');
}
else if (longdir == 'W')
Serial.print('W');
Serial.print(' ');
Serial.print((longitude/10000)%100, DEC); Serial.print('\''); Serial.print(' ');
Serial.print((longitude%10000)*6/1000, DEC); Serial.print('.');
Serial.print(((longitude%10000)*6/10)%100, DEC); Serial.println('"');
Serial.println();
}
finished=millis();
Serial.println("Finished");
elapsed=finished-start;
Serial.print(elapsed);
Serial.println(" milliseconds for serialGPS() function");
Serial.println();
}
Moderator edit: colour tags replaced by code tags.