Forum - MCS Electronics

 

FAQFAQ SearchSearch RegisterRegister Log inLog in

How to split string

 
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    www.mcselec.com Forum Index -> BASCOM-AVR Archive
View previous topic :: View next topic  
Author Message
kimmi

Moderator



Joined: 24 Feb 2006
Posts: 1922
Location: Denmark

denmark.gif
PostPosted: Mon Aug 07, 2006 10:02 pm    Post subject: How to split string Reply with quote

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
Cool 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 ?

Embarassed

_________________
/ Kim
Back to top
View user's profile Visit poster's website MSN Messenger
ATIU

Bascom Member



Joined: 15 Oct 2004
Posts: 528

philippines.gif
PostPosted: Mon Aug 07, 2006 11:14 pm    Post subject: Reply with quote

These are fix lenght, use MID function and Val to get the value from string.
Back to top
View user's profile
Luciano

Bascom Member



Joined: 29 Nov 2004
Posts: 3149
Location: Italy

blank.gif
PostPosted: Mon Aug 07, 2006 11:41 pm    Post subject: Reply with quote

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
View user's profile
oe9vfj

Moderator



Joined: 17 Jun 2004
Posts: 269
Location: Austria, Hard

austria.gif
PostPosted: Tue Aug 08, 2006 12:41 pm    Post subject: Reply with quote

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
View user's profile Visit poster's website
Luciano

Bascom Member



Joined: 29 Nov 2004
Posts: 3149
Location: Italy

blank.gif
PostPosted: Wed Aug 09, 2006 11:46 am    Post subject: Reply with quote

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
View user's profile
oe9vfj

Moderator



Joined: 17 Jun 2004
Posts: 269
Location: Austria, Hard

austria.gif
PostPosted: Wed Aug 09, 2006 1:12 pm    Post subject: Reply with quote

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
View user's profile Visit poster's website
oe9vfj

Moderator



Joined: 17 Jun 2004
Posts: 269
Location: Austria, Hard

austria.gif
PostPosted: Wed Aug 09, 2006 2:12 pm    Post subject: Reply with quote

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
View user's profile Visit poster's website
Luciano

Bascom Member



Joined: 29 Nov 2004
Posts: 3149
Location: Italy

blank.gif
PostPosted: Wed Aug 09, 2006 11:51 pm    Post subject: Reply with quote

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
View user's profile
kimmi

Moderator



Joined: 24 Feb 2006
Posts: 1922
Location: Denmark

denmark.gif
PostPosted: Fri Aug 11, 2006 12:20 am    Post subject: Reply with quote

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
Rolling Eyes

_________________
/ Kim
Back to top
View user's profile Visit poster's website MSN Messenger
Peter Klein

Bascom Member



Joined: 07 Dec 2004
Posts: 3
Location: Germany

PostPosted: Fri Aug 11, 2006 12:40 pm    Post subject: Reply with quote

Hello Joseph,
how do I get the library "GetToken.Lib". I cannot find a link to download it.
Best Regards, Peter
Back to top
View user's profile
kimmi

Moderator



Joined: 24 Feb 2006
Posts: 1922
Location: Denmark

denmark.gif
PostPosted: Fri Aug 11, 2006 12:45 pm    Post subject: Reply with quote

Hi Peter ...

check if your are login
else you cant see the files

Exclamation

_________________
/ Kim
Back to top
View user's profile Visit poster's website MSN Messenger
Display posts from previous:   
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    www.mcselec.com Forum Index -> BASCOM-AVR Archive All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
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