|
|
View previous topic :: View next topic |
Author |
Message |
JerryR
Joined: 07 Feb 2008 Posts: 167
|
A little guidance using strtok please |
Posted: Thu Mar 27, 2008 10:23 am |
|
|
I am attempting to parse comma separated fields from a GPS-generated (nmea-0183) array of chars using strtok. I am running into a problem that I need help with. Using 3.249 PCWH compiling code for a PIC18F4525 controller.
Here a code snippet:
Code: |
{
float UTC; //Complete UTC float
int8 UTC_Hours; //UTC hours
int8 UTC_Mins; //UTC min
int8 UTC_Secs_Int; //UTC seconds
int16 UTC_Secs_Frac; //UTC frac seconds
char Status;
float Lat; //Complete Lat. float
int8 Lat_Deg; //Lat. Degrees
int8 Lat_Min; //Lat. Minutes
int16 Lat_Min_Frac; //Lat. Frac Minutes
char N_S; //North =1, S =0
float Lon; //Complete Lon. float
int8 Lon_Deg; //Long. Degrees
int8 Lon_Min; //Long. Minutes
int16 Lon_Min_Frac; //Long. Frac Minutes
char E_W; //East =1, W =1
float Speed; //Complete speed float
float Course; //Complete course float
int32 Date; //complete date
int8 Rx_CheckSum; //8 bit checksum received
char Term[1];
int8 Index;
char *Field;
strcpy(Term,","); //load delimiter ","
Field = strtok(Working_GPS_Str, Term); //parse to next delimiter
UTC = atof(strtok(0, Term)); //get UTC time float
Status = strtok(0, Term); //get status char (A or V)
Lat = atof(strtok(0, Term)); //get latitude float
N_S = strtok(0, Term); //get N_S char (N or S)
Lon = atof(strtok(0, Term)); //get longitude float
E_W = strtok(0, Term); //get E_W char (E or W)
Speed = atof(strtok(0, Term)); //get speed float
Course = atof(strtok(0, Term)); //get course float
Date = atoi32(strtok(0, Term)); //get date
delay_us(1); //stopping point for
//debugger
|
The ASCII string to parse is:
$GPRMC,161229.487.A,3723.2475,N,12158.3416,W,0.13,309.62,120598,,*10
All number (float) are parsed fine. However the "A", "N", "W" are parsed incorrectly. The results are: Status= '2' (0x32), N_S= '>', and E_W= 'K'.
Anyone see my mistake?
Thanks in advance! |
|
|
Matro Guest
|
|
Posted: Thu Mar 27, 2008 10:34 am |
|
|
Just add a line at the beginning where you set the string to parse. Just to see if the problem isn't there. Use a constant string for demo.
Matro. |
|
|
JerryR
Joined: 07 Feb 2008 Posts: 167
|
|
Posted: Thu Mar 27, 2008 10:57 am |
|
|
Thanks for the quick reply Matro. Good suggestion, but still same result. The solution will probably be pretty simple. Here's the code with the "canned" GPS string forced into it.
Code: |
Parse_CkSum_GPS(*Working_GPS_Str)
{
float UTC; //Complete UTC float
int8 UTC_Hours; //UTC hours
int8 UTC_Mins; //UTC min
int8 UTC_Secs_Int; //UTC seconds
int16 UTC_Secs_Frac; //UTC frac seconds
char Status;
float Lat; //Complete Lat. float
int8 Lat_Deg; //Lat. Degrees
int8 Lat_Min; //Lat. Minutes
int16 Lat_Min_Frac; //Lat. Frac Minutes
char N_S; //North =1, S =0
float Lon; //Complete Lon. float
int8 Lon_Deg; //Long. Degrees
int8 Lon_Min; //Long. Minutes
int16 Lon_Min_Frac; //Long. Frac Minutes
char E_W; //East =1, W =1
float Speed; //Complete speed float
float Course; //Complete course float
int32 Date; //complete date
int8 Rx_CheckSum; //8 bit checksum received
char Term[1];
int8 Index;
char *Field;
strcpy (Working_GPS_Str, "GPRMC,161229.487,A,3723.2475,N,12158.3416,W,0.13,309.62,120598");
strcpy(Term,","); //load delimiter ","
Field = strtok(Working_GPS_Str, Term); //parse to next delimiter
UTC = atof(strtok(0, Term)); //get UTC time float
Status = strtok(0, Term); //get status char (A or V)
Lat = atof(strtok(0, Term)); //get latitude float
N_S = strtok(0, Term); //get N_S char (N or S)
Lon = atof(strtok(0, Term)); //get longitude float
E_W = strtok(0, Term); //get E_W char (E or W)
Speed = atof(strtok(0, Term)); //get speed float
Course = atof(strtok(0, Term)); //get course float
Date = atoi32(strtok(0, Term)); //get date
delay_us(1);
|
|
|
|
JerryR
Joined: 07 Feb 2008 Posts: 167
|
|
Posted: Thu Mar 27, 2008 11:02 am |
|
|
And another thing... It doesn't matter what character I put in the "A" position, the result for Status is still '2' (ASCII).
Any other thoughts? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Mar 27, 2008 11:07 am |
|
|
Strip the program down to essentials. Use a very short test string
that consists just of "A,B,C" or something like that. Get rid of most
of those variables. Then try to parse out the A,B,C chars. Post a
complete, compilable test program, with the #include,#fuses, #use
delay, and a main() and the printf() statement that displays the result
of the parsing. In other words, post a (very short -- 10 lines) program
that I can copy and paste into MPLAB and run in the MPSIM simulator.
Also post your compiler version. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Mar 27, 2008 11:29 am |
|
|
Code: | char Term[1];
...
strcpy(Term,","); //load delimiter "," | Your Term array should be large enough to contain the string + terminating zero. Now it is 1 character too small and strcpy will overwrite memory with unpredictable results.
Second problem: Code: | Status = strtok(0, Term); //get status char (A or V) | Strtok returns a pointer, not a value. |
|
|
JerryR
Joined: 07 Feb 2008 Posts: 167
|
|
Posted: Thu Mar 27, 2008 12:08 pm |
|
|
ckielstra, PCM:
Thanks for your replies. Yes, Yes strtok returns a pointer! I dropped my "*".
Thanks so much! |
|
|
Matro Guest
|
|
Posted: Thu Mar 27, 2008 12:14 pm |
|
|
I just think the same thing.
strtok() returns a pointer and not a value.
That's why it works when you use atof() that takes a pointer too in parameter.
Use that code:
Code: |
UTC = atof(strtok(0, Term)); //get UTC time float
Status = *strtok(0, Term); //get status char (A or V)
Lat = atof(strtok(0, Term)); //get latitude float
N_S = *strtok(0, Term); //get N_S char (N or S)
Lon = atof(strtok(0, Term)); //get longitude float
E_W = *strtok(0, Term); //get E_W char (E or W)
Speed = atof(strtok(0, Term)); //get speed float
Course = atof(strtok(0, Term)); //get course float
Date = atoi32(strtok(0, Term));
|
Matro |
|
|
Guest
|
Thanks Matro |
Posted: Thu Mar 27, 2008 12:33 pm |
|
|
Matro:
Yes, that's what I did to fix it. I didn't catch the pointer issue!
Thanks for your interest! |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|