Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : Micromite Firmware Update V5.04.04
Page 2 of 2 | |||||
Author | Message | ||||
CaptainBoing Guru Joined: 07/09/2016 Location: United KingdomPosts: 1985 |
To fix your problem you need to split the string twice (because you have two delimiters (, and *) so first I would break the string into the main components (on the ,) and for the last you need to split it on the * Geoff's code above is a good fit but it is specific to your needs. SPLIT is more aimed at general use. This is a classic example of two adages: 1. horses for courses. 2. You can have it small and slow or big and fast. This last point is the eternal challenge in writing algorithms. i.e. do I calculate a Sine from a polynomial or look it up in a table. The first is small code but takes time to run through the loops required, the last is a few steps but requires a huge data table. It is always a trade-off I have a screen dump (including the test prog) at the end of this so you can play but the way I see it here are the for/against for both methods: FIELD$: Cons. code runs each time you extract a part, Many parts = many calls. Doesn't tell you how many fields are in the string - you need to know beforehand. Doesn't permit long delimiters (e.g CRLF) but easy to fix. Pros. Small memory overhead ,no array = "cheaper" on RAM. Preserves the original string. May still end up in the firmware SPLIT: Cons. Potentially large memory overhead, maximum would be 129*256 bytes =32k+ worst case. Destroys the original string (easily fixed). Pros. single call required to extract multiple elements. Quick for many elements. Tells you how many are in the string. For the string you supplied, SPLIT used 4K of RAM(!) but it was around 3x quicker - see point 2 above as an aside here, this is not entirely a fair impression as Geoff's code has not been optimized for speed and SPLIT has. That said, With a 3 field string, split was 36mS and FIELD$ was 46mS (remember this is at 5MHz to make the delays show) I did a version without the print (the console time will make things look bad). The single call to SPLIT took 107mS and twelve calls to FIELD$ took 365mS. This absolutely must not be seen as a "my code's better than your code" bun fight - it really is just down to the differences and trade-offs in two different approaches to the same problem - also Geoff's version does cater for two different delimiters where as in this specific case, SPLIT would require to to pick apart SP$(12) (you could get SPLIT to do it but it would destroy your previous split as SP$() is re-used) If FIELD$ does make it into the firmware (so not interpreted), I will probably never use SPLIT again. Make your own mind up - here's my screen output > cpu 5 > ? mm.ver 5.0404 > ? mm.device$ Micromite MkII > list all Dim a$ Dim n,x As integer a$="$GPRMC,034600,A,3747.3072,S,14502.7606,E,000.0,097.2,081016,011.6,E*6A" Timer=0 x=split(a$,",") For n=1 To x Print sp$(n) Next Print Timer;"mS" a$="$GPRMC,034600,A,3747.3072,S,14502.7606,E,000.0,097.2,081016,011.6,E*6A" Timer=0 For n=1 To 12 Print Field$(a$,n,",") Next Print Timer;"mS" Function Split(a$,b$) ' returns the number of dimensions in SP$ always starts from 1 regardless of OPTION BASE Local INTEGER z,n,m On ERROR SKIP 1' if SP$ doesn't exist, next line will cause an error Erase SP$ z=1:n=0 Do 'count instances of delimiter for DIM SP$() z=Instr(z,a$,b$) If z=0 Then If n=0 Then ' no delimeters Dim SP$(1):SP$(1)=a$:Split=1:Exit Function ' early bath Else Exit Do End If Else n=n+1:z=z+Len(b$) End If Loop m=n+1:n=1 Dim SP$(m) Do z=Instr(1,a$,b$) If z=0 Then SP$(m)=a$:Exit Do Else SP$(n)=Left$(a$,z-1):a$=Mid$(a$,z+Len(b$)):n=n+1 End If Loop Split=m End Function '------------------------------------------------------------------------------ ' Geoff's Message Field$ Routine (with one amendment) '------------------------------------------------------------------------------ Function Field$(s$, n, delim$) Local Integer i, StartIdx = 1, EndIdx ' get the start of the field in StartIdx For i = 2 To n StartIdx = Instr(StartIdx, s$, delim$) + 1 If StartIdx = 1 Or StartIdx > Len(s$) Then Exit Function Next i ' get the end of the field in EndIdx and extract the field EndIdx = Instr(StartIdx, s$, delim$) If EndIdx = 0 Then EndIdx = Len(s$)+1 ' makes it smaller than 255 Field$ = Mid$(s$, StartIdx, EndIdx - StartIdx) End Function > RUN $GPRMC 034600 A 3747.3072 S 14502.7606 E 000.0 097.2 081016 011.6 E*6A 128mS $GPRMC 034600 A 3747.3072 S 14502.7606 E 000.0 097.2 081016 011.6 E*6A 364mS > memory Flash: 2K ( 3%) Program (76 lines) 1K ( 1%) 2 Saved Variables (40 bytes) 57K (96%) Free RAM: 4K ( 7%) 4 Variables 0K ( 0%) General 46K (93%) Free > |
||||
Andrew_G Guru Joined: 18/10/2016 Location: AustraliaPosts: 842 |
Hi Captain Boing. Thanks for that. I was "less than precise than normal" in that my comment about missing the last field was directed at the Field function by Geoff (that you modified slightly). I have not tried the Split function as I am dealing with NMEA sentences and I know how many fields there are in each. You are right that it is (always|usually?) horses for courses. One of the beaut things about this forum is that people can exchange ideas without being defensive - in my 6+ months here I've not seen one example. Cheers, Andrew |
||||
led-bloon Senior Member Joined: 21/12/2014 Location: AustraliaPosts: 203 |
One point with Geoff's FIELD$ code, I bring up for discussion, especially if it were to be re-introduced into MMBasic. FIELD$ should return ALL characters between delimiters. My view is that the "trim leading and trailing spaces" code at the bottom should not exist in the function. The coder should be responsible for removing unwanted white space if and when required. Miss you George |
||||
Geoffg Guru Joined: 06/06/2011 Location: AustraliaPosts: 3165 |
Yep, I fully agree. I debated it with myself before putting it in but should have left the Trim$() function as separate. Geoff Geoff Graham - http://geoffg.net |
||||
CaptainBoing Guru Joined: 07/09/2016 Location: United KingdomPosts: 1985 |
yes this is really important. If the firmware starts hiding stuff trying to be helpful (with the best intentions), it can still bite you in the rear. One famous one in VB was forcing the password for the MSFTP ActiveX object into lower case caused a few WTF moments when first discovered in the early 90's |
||||
Page 2 of 2 |
Print this page |