View previous topic :: View next topic |
Author |
Message |
kimmi
Joined: 24 Feb 2006 Posts: 1922 Location: Denmark
|
Posted: Mon Aug 07, 2006 10:02 pm Post subject: How to split string |
|
|
Hi all ...
Working on the last part on my GPS Tracker and need help
Now I cant see how to get a largs string split up using (,) as split
here is my string
Code: | GPGGA,191410,4735.5634,N,00739.3538,E,1,04,4.4,351.5,M,48.0,M,,*45 |
the len betwin to (,) can variat from 0 to 6 chr
in vb it is easy just use Split have read the help finl but don´t get it in to my littel head ( sorry)
need to split it in 15 parts here is smal info about parts
NMEA 0183 Datensätze
GGA - Global Positioning System Fix Data, Time, Position and fix related data fora GPS receiver.
11
1 2 3 4 5 6 7 8 9 10 | 12 13 14 15
| | | | | | | | | | | | | | |
$--GGA,hhmmss.ss,llll.ll,a,yyyyy.yy,a,x,xx,x.x,x.x,M,x.x,M,x.x,xxxx*hh<CR><LF>
Field Number:
1) Universal Time Coordinated (UTC)
2) Latitude
3) N or S (North or South)
4) Longitude
5) E or W (East or West)
6) GPS Quality Indicator,
0 - fix not available,
1 - GPS fix,
2 - Differential GPS fix
7) Number of satellites in view, 00 - 12
Horizontal Dilution of precision
9) Antenna Altitude above/below mean-sea-level (geoid)
10) Units of antenna altitude, meters
11) Geoidal separation, the difference between the WGS-84 earth
ellipsoid and mean-sea-level (geoid), "-" means mean-sea-level
below ellipsoid
12) Units of geoidal separation, meters
13) Age of differential GPS data, time in seconds since last SC104
type 1 or 9 update, null field when DGPS is not used
14) Differential reference station ID, 0000-1023
15) Checksum
is it posibel ?
_________________ / Kim |
|
Back to top |
|
|
ATIU
Joined: 15 Oct 2004 Posts: 534
|
Posted: Mon Aug 07, 2006 11:14 pm Post subject: |
|
|
These are fix lenght, use MID function and Val to get the value from string. |
|
Back to top |
|
|
Luciano
Joined: 29 Nov 2004 Posts: 3149 Location: Italy
|
Posted: Mon Aug 07, 2006 11:41 pm Post subject: |
|
|
Hi,
EDIT:
I have removed my code with INSTR and MID.
See next post from Josef which is exactly what you need.
By the way, I just realized that Bascom has also similar function which is SPLIT.
Below is a sample using it.
Best regards,
Luciano
SPLIT sample:
Code: |
Dim Gps_data as string * 100
Dim My_Array(20) As String * 15
Dim Bcount As Byte
Dim I As Byte
gps_data = "GPGGA,191410,4735.5634,,00739.3538,E,1,04,4.4,351.5,M,48.0,M,,*45"
Print gps_data
Print "======================================="
Bcount = Split(gps_data , My_Array(1) , ",")
For I = 1 To Bcount
print My_Array(I)
Next
End |
The output:
Code: | GPGGA,191410,4735.5634,,00739.3538,E,1,04,4.4,351.5,M,48.0,M,,*45
=======================================
GPGGA
191410
4735.5634
00739.3538
E
1
04
4.4
351.5
M
48.0
M
*45
|
Last edited by Luciano on Tue Aug 08, 2006 3:00 pm; edited 3 times in total |
|
Back to top |
|
|
oe9vfj
Joined: 17 Jun 2004 Posts: 269 Location: Austria, Hard
|
Posted: Tue Aug 08, 2006 12:41 pm Post subject: |
|
|
Hi,
As I am going to play with GPS in near future, I thought about a function to separate token from such a string.
I wrote a function for that reason and put it in a Library.
You can use it this way:
Code: | Declare Function GetToken (strInput as String, byval bSeparator as Byte, byval bCount as Byte ) as String
$LIB "GetToken.Lib"
$EXTERNAL GetToken
Dim str1 as String * 100
Dim str2 as String * 20
Dim StrSep as Byte
strSep = asc(",")
Dim i As byte
str1 = "GPGGA,191410,4735.5634,N,00739.3538,E,1,04,4.4,351.5,M,48.0,M,,*45"
for i = 1 to 20
str2 = Gettoken(str1, strSep, i)
print ">" ; str2 ; "<"
next
end |
The output of the example will look like this:
Quote: | >GPGGA<
>191410<
>4735.5634<
>N<
>00739.3538<
>E<
>1<
>04<
>4.4<
>351.5<
>M<
>48.0<
>M<
><
>*45<
><
><
><
><
>< |
> and < are used in the output to show empty strings too.
In simple way, if you want the seventh token from a string (separeted by , ) you can use:
Code: | str2 = GetToken(str1,44 ,7) ' 44 is ASCII-Value of comma (,) |
Copy the file GetToken.Lib to your Lib-Path of BASCOM-AVR
I hope you can use it. _________________ regards Josef
DOS - File System for BASCOM-AVR on http://members.aon.at/voegel |
|
Back to top |
|
|
Luciano
Joined: 29 Nov 2004 Posts: 3149 Location: Italy
|
Posted: Wed Aug 09, 2006 11:46 am Post subject: |
|
|
Code: |
' Luciano 8/9/2006
'
' (See first the LIB posted by Josef in this thread).
'
' With this code I have tried to replicate in Basic what the LIB
' posted by Josef does. The function in the LIB is written
' in assembly so it is much faster than the code below.
' When I have more time I will compare the speed of the
' two solutions and post the results.(Just a call without PRINT).
'
' * * * *
'
' The function Get_Token_X
'
' - The input string is passed by reference.
'
' - The separator character and the token number are passed by value so that
' the separator character can be a string constant "," or a string variable.
' Same for the token number which can be a constant or a byte variable.
' (The sample code below uses both).
'
'
$regfile = "M128def.dat"
$crystal = 16000000
$hwstack = 40
$swstack = 40
$framesize = 32
$baud = 9600
Declare Function Get_Token_X(Input_String As String , Byval Separator_Chr As String , Byval Token_Nr As Byte) As String
Dim Gps_Data As String * 80
Dim My_Field As String * 15
Dim Chr_Sep As String * 1
Dim I As Byte
Gps_Data = "GPGGA,191410,4735.5634,N,00739.3538,E,1,04,4.4,351.5,M,48.0,M,,*45"
Print "Input string: " ; Gps_Data
Print ""
Print "======================================="
Print " Get tokens 1 to 20 "
Print ""
For I = 1 To 20
My_Field = Get_Token_X(Gps_Data , "," , I)
Print "Token #" ; I ; ": >" ; My_Field ; "<"
Next
Print "======================================="
Print " Get tokens random"
Print ""
Chr_sep = ","
My_Field = Get_Token_X(Gps_Data , "," , 1)
Print "Token #1: >" ; My_Field ; "<"
My_Field = Get_Token_X(Gps_Data , Chr_Sep , 3)
Print "Token #3: >" ; My_Field ; "<"
My_Field = Get_Token_X(Gps_Data , Chr_Sep , 14)
Print "Token #14: >" ; My_Field ; "<"
My_Field = Get_Token_X(Gps_Data , Chr_Sep , 15)
Print "Token #15: >" ; My_Field ; "<"
My_Field = Get_Token_X(Gps_Data , Chr_Sep , 16)
Print "Token #16: >" ; My_Field ; "<"
My_Field = Get_Token_X(Gps_Data , Chr_Sep , 17)
Print "Token #17: >" ; My_Field ; "<"
'Token # = 0 is not a valid value. (1-255)
My_Field = Get_Token_X(Gps_Data , "," , 0)
Print "Token #0: >" ; My_Field ; "<"
End
' *********************************
Function Get_Token_X(Input_String As String , Separator_Chr As String , Token_Nr As Byte) As String
Local Token_Count As Byte
Local String_Pos As Byte
Local Input_String_Length as Byte
Local Current_Chr As String * 1
Input_String_Length = Len(Input_String)
String_Pos = 0
Token_Count = 0
Get_Token_X = ""
Do
Incr String_Pos
Current_Chr = Mid(Input_String , String_Pos , 1)
If Current_Chr = Separator_Chr Then
Incr Token_Count
If Token_Count = Token_Nr Then
Exit Function
Else
Get_Token_X = ""
End if
Else
Get_Token_X = Get_Token_X + Current_Chr
End If
Loop Until String_Pos = Input_String_Length
Incr Token_Count
' If the user asks for more than the tokens present in the string
If Token_Nr > Token_Count Then
Get_Token_X = "Not present"
' Get_Token_X = "" 'use that to return an empty string
End If
' The token # must be 1-255. This will print Error if the user ask token # 0.
If Token_Nr = 0 Then
Get_Token_X = "Error"
End If
End Function
|
The output:
Code: | Input string: GPGGA,191410,4735.5634,N,00739.3538,E,1,04,4.4,351.5,M,48.0,M,,*45
=======================================
Get tokens 1 to 20
Token #1: >GPGGA<
Token #2: >191410<
Token #3: >4735.5634<
Token #4: >N<
Token #5: >00739.3538<
Token #6: >E<
Token #7: >1<
Token #8: >04<
Token #9: >4.4<
Token #10: >351.5<
Token #11: >M<
Token #12: >48.0<
Token #13: >M<
Token #14: ><
Token #15: >*45<
Token #16: >Not present<
Token #17: >Not present<
Token #18: >Not present<
Token #19: >Not present<
Token #20: >Not present<
=======================================
Get tokens random
Token #1: >GPGGA<
Token #3: >4735.5634<
Token #14: ><
Token #15: >*45<
Token #16: >Not present<
Token #17: >Not present<
Token #0: >Error< |
|
|
Back to top |
|
|
oe9vfj
Joined: 17 Jun 2004 Posts: 269 Location: Austria, Hard
|
Posted: Wed Aug 09, 2006 1:12 pm Post subject: |
|
|
Hi Luciano
Here is the Speed Compare (CPU-Cycles) with the above mentioned string.
Token# - Basic / ASM(Lib)
1 - 1707 / 157
8 - 14201 / 419
15 - 26673 / 602
I adapted my routine according to idea of Luciano to check for token# between 1 and 255 and separator ASCII-Value between 1 and 255 (No empty String)
Not matching parameter (Token# = 0 or ASCII-Value of separator character = 0 or empty string) with return an empty string.
You can download new version here.
BTW: You can passing a String(1) to the function for the parameter "Separator Character" with following declaration:
Code: | Declare Function GetToken (strInput as String, byval bSeparator as String, byval bCount as Byte ) as String |
to use it like:
Code: | str2 = GetToken ( str1, ",", 7) |
The first character of the passed string will taken as Separation Character. This increase CPU-Cycles of 63 cycles if the string is passed byval. _________________ regards Josef
DOS - File System for BASCOM-AVR on http://members.aon.at/voegel |
|
Back to top |
|
|
oe9vfj
Joined: 17 Jun 2004 Posts: 269 Location: Austria, Hard
|
Posted: Wed Aug 09, 2006 2:12 pm Post subject: |
|
|
Hi,
I have just seen, that there is just a function implemented in BASCOM-AVR, which splits such a GPS String into an array.
Check the function SPLIT. _________________ regards Josef
DOS - File System for BASCOM-AVR on http://members.aon.at/voegel |
|
Back to top |
|
|
Luciano
Joined: 29 Nov 2004 Posts: 3149 Location: Italy
|
Posted: Wed Aug 09, 2006 11:51 pm Post subject: |
|
|
Hi Josef,
I am aware of the Bascom function SPLIT. SPLIT works well but
you need a string array with array elements big enough to
hold the largest field present in the input string.
In our case here (GPS) the used RAM would be:
10 bytes * 15 fields = 150 bytes
I have written a new version of my function in Basic.
Your assembly function is still 10x faster.
Best regards,
Luciano
Code: |
' Luciano 8/9/2006
'
' Get_Token_X
'
' New version of the function Get_Token_X written in Basic.
' The new version of the function does not use MID and avoids
' the use of strings where possible. The function is 4x faster
' than the previous version when token #15 is retrieved.
'
' =========================================================================
' SPEED TEST
'
' Input string : GPGGA,191410,4735.5634,N,00739.3538,E,1,04,4.4,351.5,M,48.0,M,,*45
' Used call: Get_Token_X(Gps_Data , "," , 15) [See sample below].
'
' Get Token #1 = 939 CPU-Cycles (Old version 1707 CPU-Cycles)
' Get Token #8 = 3896 CPU-Cycles (Old version 14201 CPU-Cycles)
' Get Token #15 = 6067 CPU-Cycles (Old version 26673 CPU-Cycles)
'
' The assembly version written by Josef is still 10 times faster.
'
' Get Token #1 = 157 CPU-Cycles (6x faster than my Basic code)
' Get Token #8 = 417 CPU-Cycles (9.3x faster than my Basic code)
' Get Token #15 = 602 CPU-Cycles (10x faster than my Basic code)
'
' =========================================================================
'
' The function Get_Token_X
'
' - The input string is passed by reference.
'
' - The separator character and the token number are passed by value so that
' the separator character can be a string constant "," or a string variable.
' Same for the token number which can be a constant or a byte variable.
' (The sample code below uses both).
'
'
$regfile = "M128def.dat"
$crystal = 16000000
$hwstack = 40
$swstack = 40
$framesize = 32
$baud = 9600
Declare Function Get_Token_X(Input_String As String , Byval Separator_Chr As String , Byval Token_Nr As Byte) As String
Dim Gps_Data As String * 80
Dim My_Field As String * 15
Dim Chr_Sep As String * 1
Dim I As Byte
Gps_Data = "GPGGA,191410,4735.5634,N,00739.3538,E,1,04,4.4,351.5,M,48.0,M,,*45"
Print "Input string: " ; Gps_Data
Print ""
Print "======================================="
Print " Get tokens 1 to 20 "
Print ""
For I = 1 To 20
My_Field = Get_Token_X(Gps_Data , "," , I)
Print "Token #" ; I ; ": >" ; My_Field ; "<"
Next
Print "======================================="
Print " Get tokens random"
Print ""
Chr_sep = ","
My_Field = Get_Token_X(Gps_Data , "," , 1)
Print "Token #1: >" ; My_Field ; "<"
My_Field = Get_Token_X(Gps_Data , Chr_Sep , 3)
Print "Token #3: >" ; My_Field ; "<"
My_Field = Get_Token_X(Gps_Data , Chr_Sep , 14)
Print "Token #14: >" ; My_Field ; "<"
My_Field = Get_Token_X(Gps_Data , Chr_Sep , 15)
Print "Token #15: >" ; My_Field ; "<"
My_Field = Get_Token_X(Gps_Data , Chr_Sep , 16)
Print "Token #16: >" ; My_Field ; "<"
My_Field = Get_Token_X(Gps_Data , Chr_Sep , 17)
Print "Token #17: >" ; My_Field ; "<"
' Token # = 0 is not a valid value. (1-255)
My_Field = Get_Token_X(Gps_Data , "," , 0)
Print "Token #0: >" ; My_Field ; "<"
End
' *********************************
Function Get_Token_X(Input_String As String , Separator_Chr As String , Token_Nr As Byte) As String
Local Token_Count As Byte
Local String_Pointer As Word
Local Byte_Read As Byte
Local Separator_Byte As Byte
Token_Count = 1
Get_Token_X = ""
Separator_byte = Asc(Separator_Chr)
String_Pointer = Varptr(Input_String)
Do
Byte_Read = Inp(String_Pointer)
Incr String_Pointer
If Byte_Read = Separator_Byte Then
If Token_Count = Token_Nr Then
Exit Function
End if
Incr Token_Count
Else
If Token_Count = Token_Nr Then
Get_Token_X = Get_Token_X + Chr(Byte_Read)
End If
End If
Loop Until Byte_Read = 0
' If the user asks for more than the tokens present in the string
If Token_Nr > Token_Count Then
Get_Token_X = "Not present"
' Get_Token_X = "" 'use that to return an empty string
End If
' The token # must be 1-255. This will print Error if the user ask token # 0.
If Token_Nr = 0 Then
Get_Token_X = "Error"
End If
End Function |
|
|
Back to top |
|
|
kimmi
Joined: 24 Feb 2006 Posts: 1922 Location: Denmark
|
Posted: Fri Aug 11, 2006 12:20 am Post subject: |
|
|
Hi Luciano & Josef ..
tnx. for the help now i try to make the last part
time is critial have 0.7 sec between update on gsp right now
using a M128 at 16 mhz baud 19200 the ( AVR-MT-128 board from spark )
40*4 lcd
here is the strings i have to handle and split up
date - time line 1 on lcd
latitude - longitude line 2
speed -
save every 1 min in eeprom if (save is enable thu sms) in eeprom to use for sending reply sms
may have to set GPS to update every 2 sec insted of 1 sec
$GPGGA,230439.175,5729.4504,N,00956.3053,E,1,07,2.1,51.8,M,42.1,M,0.0,0000*42
$GPVTG,,T,,M,0.000000,N,0.000000,K*4
again Tnx
Have a nice Weekend
_________________ / Kim |
|
Back to top |
|
|
Peter Klein
Joined: 07 Dec 2004 Posts: 3 Location: Germany
|
Posted: Fri Aug 11, 2006 12:40 pm Post subject: |
|
|
Hello Joseph,
how do I get the library "GetToken.Lib". I cannot find a link to download it.
Best Regards, Peter |
|
Back to top |
|
|
kimmi
Joined: 24 Feb 2006 Posts: 1922 Location: Denmark
|
Posted: Fri Aug 11, 2006 12:45 pm Post subject: |
|
|
Hi Peter ...
check if your are login
else you cant see the files
_________________ / Kim |
|
Back to top |
|
|
|
|
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 You cannot attach files in this forum You cannot download files in this forum
|
|