I have a gps unit hooked up to USARTD0 on my ATXmega256A3. It came out of the box at 4800 baud, I set it to 9600… I’ve been able to turn off all but the RMC message and can still query the other ones when i need them. I’ve been working with the RMC message, but this happens with the others too.
First of all, here’s the code:
void gps_parse()
{
printf("\nparsing: %s ",gps_string);
char gps_time [11];
strcpy(gps_time,"");
char gps_valid;
char gps_lattitude [10];
strcpy(gps_lattitude,"");
char gps_ns;
char gps_longitude [11];
strcpy(gps_longitude,"");
char gps_ew;
char gps_speed [5];
strcpy(gps_speed,"");
char gps_heading [7];
strcpy(gps_heading,"");
char gps_date [7];
strcpy(gps_date,"");
char* token;
char delim = ',';
token = strtok(gps_string, &delim);
if(strcmp(token,"$GPRMC") == 0)
gps_message_type = RMC;
else if (strcmp(token,"$GPGLL") == 0)
gps_message_type = GLL;
switch(gps_message_type)
{
case RMC:
strcpy(gps_time, strtok(NULL, &delim));
gps_valid = *strtok(NULL, &delim);
strcpy(gps_lattitude, strtok(NULL, &delim));
gps_ns = *strtok(NULL, &delim);
strcpy(gps_longitude, strtok(NULL, &delim));
gps_ew = *strtok(NULL, &delim);
strcpy(gps_speed, strtok(NULL, &delim));
strcpy(gps_heading, strtok(NULL, &delim));
strcpy(gps_date, strtok(NULL, &delim));
break;
default:
printf("GPS PARSE ERROR\n");
break;
}
printf("time: \n%s | ", gps_time);
printf("valid: %c | ", gps_valid);
printf("lat: %s",gps_lattitude);
printf("%c | ", gps_ns);
printf("long: %s", gps_longitude);
printf("%c | ",gps_ew);
printf("speed: %s | ", gps_speed);
printf("heading: %s | ", gps_heading);
printf("date: %s \n", gps_date);
strcpy(gps_string,"");
}
gps_string is, well, a string that has a full NMEA message. As the code executes, every time the GPS module sends a new update (1 Hz), what I see in my terminal is something like:
parsing: $GPRMC,070923.000,A,3851.1384,N,07715.5597,W,0.07,264.53,251209,,*19
time:
070923.000 | valid: A | lat: 3851.1384N | long: 07715.5597W | speed: 0.07 | heading: 264 | date: 53
which tells me that it’s entered the parsing function, with that $GPRMC string as the input so I can double-check the output.
It seems to be a problem with the strtok() function. You can see that once it gets to the value for the heading (265.53), it treats the period (“.”) as the delimiter, even though otherwise it’s been using a comma
why does it do this? what can I do about it? thanks
by the way, gps_string (the full NMEA sentence) is being populated by an ISR:
ISR(USARTD0_RXC_vect)
{
char c;
c = USARTD0.DATA;
strncat(&gps_string, &c, 1);
if (c == '\n')
{
gps_parse();
}
}