Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

reading gps info -- one little hiccup

Status
Not open for further replies.

galed

New Member
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:
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:
Code:
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. Date then gets the decimal part of heading, though it should get "251209"

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:
Code:
ISR(USARTD0_RXC_vect)
{
   char c;
   c = USARTD0.DATA;
   strncat(&gps_string, &c, 1);
   if (c == '\n')
   {
      gps_parse();
   }
}
 
I just tried you code and it worked correctly.

Mike.
 
Last edited:
I ended up changing char delim = ','; to char delim [] = ","; and the strtok calls use delim instead of &delim. that fixed it
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top