![]() |
Forum Index : Microcontroller and PC projects : Newie got a few questions
![]() ![]() ![]() ![]() |
|||||
Author | Message | ||||
MikeO Senior Member ![]() Joined: 11/09/2011 Location: AustraliaPosts: 275 |
Hi Lew, here is a function I wrote some time ago to do exactly what you are trying to do. I use this function very frequently and I have found it totaly reliable. 'Parse$, function to return a field from a delimited string 'Usage Parse$(Delimited String, Number of Field in string,[optional delimiter]) 'Delimiter defaults to comma unless specified 'eg r$=Parse$("Bat,Ball,Cricket,Pitch",3) will return "Cricket" in r$ Function Parse$(s$,FieldNumber,d$) Local String stringArg$ Local Integer intOldY,intY,intX if d$="" then d$="," endif StringArg$ = S$ + d$ intOldY = 1:intX=0:intY=0 Parse$ = "" do While intY < Len(StringArg$) And intX < FieldNumber intY = Instr(intOldY, StringArg$, d$) intX = intX + 1 If intX = FieldNumber Then parse$ = Mid$(StringArg$, intOldY, intY - intOldY) Endif intOldY = intY + 1 loop 'print s$; intx; inty; intoldy 'print fieldnumber;" ";parse$ End Function Codenquilts |
||||
lew247![]() Guru ![]() Joined: 23/12/2015 Location: United KingdomPosts: 1702 |
Thanks Mike, it will be extremely handy and I'm positive it will do what I want, BUT Unfortunately I cannot understand a lot of it I've added comments to the code with the bits I do understand and dont. IF you don't mind, could you explain what each bit does please? This will help me immensely and also anyone else who isn't good with this stuff. Lewis 'Parse$, function to return a field from a delimited string 'Usage Parse$(Delimited String, Number of Field in string,[optional delimiter]) 'Delimiter defaults to comma unless specified 'eg r$=Parse$("Bat,Ball,Cricket,Pitch",3) will return "Cricket" in r$ 'DO YOU HAVE TO HAVE Bat, Ball, Cricket and Pitch there? Function Parse$(s$,FieldNumber,d$) 'IS this the function name? not sure what s$, FieldNumber,d$ means?? Local String stringArg$ 'Local saying stringAtg$ is a string? wouldnt Local stringArg$ do the same?? Local Integer intOldY,intY,intX 'Local saying intOldY, intY, intx are integers? if d$="" then 'If d$ is empty then d$ = "," ??? d$="," endif StringArg$ = S$ + d$ 'Not sure what this does? intOldY = 1:intX=0:intY=0 ' Or this one? Parse$ = "" Parse$ is the function name? not sure why it = "" ? do While intY < Len(StringArg$) And intX < FieldNumber 'not sure that this means intY = Instr(intOldY, StringArg$, d$) 'or this intX = intX + 1 'adding 1 to intX? or something else? If intX = FieldNumber Then ' Not sure what this is? parse$ = Mid$(StringArg$, intOldY, intY - intOldY) ' umm I must seem really stupid at this point Endif intOldY = intY + 1 'intOldY = inty+1 whatever intY was it's now plus 1 and intOldy? loop 'Loop 'print s$; intx; inty; intoldy 'PRINT these values but not sure what they actually are 'print fieldnumber;" ";parse$ 'Same here End Function IF it helps anyone, this is the information coming INTO the serial port of the Micromite [quote]Today,broken clouds,04d,19.82,1024,5.1,200,77,Day2,Wed Aug 31 12:00:00 2016,light rain,10d,13.3,19.51,1024,70,5.56,200,Day3,Thu Sep 01 12:00:00 2016,few clouds,02d,10.54,19.69,1024,78,3.67,200,Day4,Fri Sep 02 12:00:00 2016,light rain,10d,12.55,17.38,1024,97,6.39,200,Day5,Sat Sep 03 12:00:00 2016,clear sky,01d,13.78,25.76,1024,0,5.52,200,Day6,Sun Sep 04 12:00:00 2016,clear sky,01d,13.42,26.85,1024,0,2.47,200 'ITEM NUMBERS - not sure if they should start at 0 or 1 1 today 2 desc today 3 icon today 4 temp today 5 pressure 6 wind speed 7 direction 8 humidity 9 day 2 10 date 2 first 3 digits on the left is day 11 desc 12 icon 13 temp min 14 temp max 15 press 16 humid 17 speed 18 dir 19 date 3 first 3 digits on the left is day 20 desc 21 icon 22 temp min 23 temp max 24 press 25 humid 26 speed 27 dir 28 date 4 first 3 digits on the left is day 29 desc 30 icon 31 temp min 32 temp max 33 press 34 humid 35 speed 36 dir 37 date 5 first 3 digits on the left is day 38 desc 39 icon 40 temp min 41 temp max 42 press 43 humid 44 speed 45 dir 46 date 6 first 3 digits on the left is day 47 desc 48 icon 49 temp min 50 temp max 51 press 52 humid 53 speed 54 dir[/quote] Basicaly I need to pull out some, or all of the above item numbers to do things with in the main program |
||||
MicroBlocks![]() Guru ![]() Joined: 12/05/2012 Location: ThailandPosts: 2209 |
You can use the same function as i posted in the LCD topic you posted. It is then very easy to use the values. The one MikeO posted also works but is a bit inefficient when you need many values as the data has to be parsed every single time. This code will parse the string in a single pass and stores each value in an array [code] 'Required Global variable for GetFieldArray function 'Dimension this variable so that it can hold all values Dim GetFieldArray$(55) Function GetFieldArray( Record$, Delimiter$, KeepQuotes ) Local Index, Char, InQuote, Count InQuote = 0 Count = 0 If Delimiter$ = "" Then Delimiter$ = "," For Index = 1 To Len(Record$) Char = Asc(Mid$(Record$, Index, 1)) If Char = 34 Then InQuote = Not InQuote If Not InQuote And Instr(Delimiter$, Chr$(char)) >= 1 Then Count = Count + 1 Else If Char <> 34 Or KeepQuotes Then GetFieldArray$(Count) = GetFieldArray$(Count) + Chr$(char) EndIf EndIf Next GetFieldArray = Count + 1 End Function [/code] You then use it like this (Here i used a space as a delimiter): [code] MyString$ = "Hello The Back Shed users." N = GetFieldArray(YourStringHere$, " ") for L = 0 to N - 1 print GetFieldArray$(L) next [/code] That will give the result: [code] Hello The Back Shed Users. [/code] In you example above you would use: [code] N = GetFieldArray(MyData$) 'You can check N if the number of fields is what you expect 'You can use any value directly by its index print GetFieldArray$(25) print GetFieldArray$(41) print GetFieldArray$(11) ... [/code] Microblocks. Build with logic. |
||||
lew247![]() Guru ![]() Joined: 23/12/2015 Location: United KingdomPosts: 1702 |
Thanks Jean I still can't get it working, at the moment the error is [quote][85] Function GetFieldArray( Record$, Delimiter$, KeepQuotes ) Error: Variable type not specified[/quote] This is how I implemented your function, not sure if I did it correct or not IF I try and include Dim GetFieldArray$(55) it comes up with this error Error: A sub/fun has the same name: GETFIELDARRAY [code]DIM MYSTRING as string OPEN "COM3:9200" AS #3 'Open port for ESP8266 IF LOC(#3) > 1 THEN SERIAL3 END IF Function GetFieldArray( Record$, Delimiter$, KeepQuotes ) Local Index, Char, InQuote, Count InQuote = 0 Count = 0 If Delimiter$ = "" Then Delimiter$ = "," For Index = 1 To Len(Record$) Char = Asc(Mid$(Record$, Index, 1)) If Char = 34 Then InQuote = Not InQuote If Not InQuote And Instr(Delimiter$, Chr$(char)) >= 1 Then Count = Count + 1 Else If Char <> 34 Or KeepQuotes Then GetFieldArray$(Count) = GetFieldArray$(Count) + Chr$(char) EndIf EndIf Next GetFieldArray = Count + 1 End Function SUB SERIAL3 Local F$ 'Define D$ only for use by this subroutine(ignores any D$ in main code) LOCAL N as float F$ = Input$(100, #3) 'Suck everything in buffer out MyString$ = F$ N = GetFieldArray(MyString$, ",") print GetFieldArray$(25) print GetFieldArray$(41) print GetFieldArray$(11) End Sub [/code] |
||||
MicroBlocks![]() Guru ![]() Joined: 12/05/2012 Location: ThailandPosts: 2209 |
try this: [code] DIM FieldArray$(55) OPEN "COM3:9200" AS #3 'Open port for ESP8266 do IF LOC(#3) > 1 THEN SERIAL3 END IF pause 500 loop Function GetFieldArray( Record$, Delimiter$, KeepQuotes ) AS INTEGER Local Index, Char, InQuote, Count InQuote = 0 Count = 0 If Delimiter$ = "" Then Delimiter$ = "," For Index = 1 To Len(Record$) Char = Asc(Mid$(Record$, Index, 1)) If Char = 34 Then InQuote = Not InQuote If Not InQuote And Instr(Delimiter$, Chr$(char)) >= 1 Then Count = Count + 1 Else If Char <> 34 Or KeepQuotes Then FieldArray$(Count) = FieldArray$(Count) + Chr$(char) EndIf EndIf Next GetFieldArray = Count + 1 End Function SUB SERIAL3 Local F$ LOCAL N as INTEGER F$ = Input$(100, #3) 'Suck everything in buffer out N = GetFieldArray(F$) print GetFieldArray$(25) print GetFieldArray$(41) print GetFieldArray$(11) End Sub [/code] To minimize the amount of memory it uses you can also add a length to the dim statement. Now each string is 255 long. I expect that the values you receive are much shorter. Figure out the longest value you can have and use that. Microblocks. Build with logic. |
||||
Phil23 Guru ![]() Joined: 27/03/2016 Location: AustraliaPosts: 1667 |
Have a look at something simple. When I was starting I wrote this to help me understand SUBS Vs FUNCTIONS. All it was for was to help me understand how they worked. Phil. [Code]'Test Function Option Explicit Dim Float x,y,Perimeter2,Area2 x=2.0 : y=3 Print "X="; x Print "Y="; y Print "Perimeter"; Perimeter(x,y) Print "Area "; Area(x,y) PerimeterAndArea(x,y,Perimeter2,Area2) Print "Perimeter"; Perimeter2 Print "Area "; Area2 Function perimeter(a,b) As Float Perimeter=(a+b)*2 End Function Function Area(a,b) Area=a*b End Function Sub PerimeterAndArea(x,y,P2,A2) P2=(x+y)*2 A2=x*y End Sub [/code] |
||||
lew247![]() Guru ![]() Joined: 23/12/2015 Location: United KingdomPosts: 1702 |
Jean a quick question what's the (55) mean? Would I be right in thinking it's the number of arrays expected? DIM FieldArray$(55) |
||||
JohnS Guru ![]() Joined: 18/11/2011 Location: United KingdomPosts: 3999 |
It's the number of what are called (array) elements. Each is a separate string, and with a default length of 255 they'll use a LOT of RAM (*). (*) on a small chip like a PIC32 - quite tiny on a Linux/Windows PC! John |
||||
lew247![]() Guru ![]() Joined: 23/12/2015 Location: United KingdomPosts: 1702 |
Thanks JohnS I'm still stuck with this error [quote]Function GetFieldArray( Record$, Delimiter$, KeepQuotes ) Error: Variable type not specified[/quote] EDIT: I can get past this error if I remove OPTION EXPLICIT BUT I then get this error [quote]Print GetFieldArray$(25) Error: Inconsistent type suffix[/quote] Edit 2: for those people who think I am not trying, I have tried various methods of using the DIM and Local statements to try and fix the errors and I have also made several changes to the GetFieldArray"(25) to try and fix the error but none of the things I have done work |
||||
JohnS Guru ![]() Joined: 18/11/2011 Location: United KingdomPosts: 3999 |
Is it an array or function or are you trying to have BOTH with the same name (which you normally can't do)? I suspect the latter. Change one of the names... John |
||||
lew247![]() Guru ![]() Joined: 23/12/2015 Location: United KingdomPosts: 1702 |
The error occurs here print GetFieldArray$(25) The Function is Function GetFieldArray( Record$, Delimiter$, KeepQuotes ) AS INTEGER Local Index, Char, InQuote, Count InQuote = 0 Count = 0 If Delimiter$ = "" Then Delimiter$ = "," For Index = 1 To Len(Record$) Char = Asc(Mid$(Record$, Index, 1)) If Char = 34 Then InQuote = Not InQuote If Not InQuote And Instr(Delimiter$, Chr$(char)) >= 1 Then Count = Count + 1 Else If Char <> 34 Or KeepQuotes Then FieldArray$(Count) = FieldArray$(Count) + Chr$(char) EndIf EndIf Next GetFieldArray = Count + 1 End Function |
||||
WhiteWizzard Guru ![]() Joined: 05/04/2013 Location: United KingdomPosts: 2927 |
Immediately spotted that GetfieldArray$(25) is referring to a string array (because of the $ symbol) but the function is GetFieldArray(....) AS INTEGER which is obviously not a string. So one minute it is being referenced as a string, and then as an integer. These lead to the Inconsistent Type Suffix message ![]() I am still 'baffled' by option explicit. In my simple world I use $ to represent a string, and floats and integers as needed. I ensure no two variables have the same name - this seems to work well for me. |
||||
WhiteWizzard Guru ![]() Joined: 05/04/2013 Location: United KingdomPosts: 2927 |
Im just checking: Did you need PRINT FieldArray$(25) as opposed to Print GetFieldArray$(25)? |
||||
lew247![]() Guru ![]() Joined: 23/12/2015 Location: United KingdomPosts: 1702 |
Nice try Phil I removed the AS INTEGER but it still throws the same error |
||||
lew247![]() Guru ![]() Joined: 23/12/2015 Location: United KingdomPosts: 1702 |
I just had a thought If GetFieldArray$ is a function then surely I can't print it? I think I should be PRINT N(25) EDIT: Yes it was PRINT N(25) it's not quite right yet but hopefully I can figure it out now Thanks everyone ![]() |
||||
WhiteWizzard Guru ![]() Joined: 05/04/2013 Location: United KingdomPosts: 2927 |
Your Function is called GetFieldArray. There is no $. Has MicroBlocks confirmed his code runs? He is indeed printing GetFieldArray$ in his code; but at the beginning he says 'try this...' (so not sure if code was tested). I really dislike having two variables/functions/subs with the same name; and even more so having a string with the same name as a number. It can lead to all types of confusion as we are seeing here in this thread! I will take a look at code here on a MM and see if I can help uncover things . . . WW |
||||
WhiteWizzard Guru ![]() Joined: 05/04/2013 Location: United KingdomPosts: 2927 |
Before I fire things up, what happens when you type: PRINT FieldArray$(25) |
||||
lew247![]() Guru ![]() Joined: 23/12/2015 Location: United KingdomPosts: 1702 |
Thanks Phil I have it "kinda" running, it's printing before all the data is received at the moment, so data is still coming in while it's printing I'll try splitting the print coming OUT of the ESP into different blocks, then look for a start array to see print sub it goes to Hope that made sense, I can see it in my mind but putting it into words is difficult |
||||
WhiteWizzard Guru ![]() Joined: 05/04/2013 Location: United KingdomPosts: 2927 |
The more I look at it, the more I am convinced it should be PRINT FieldArray(xx) You simply use: N=GetFieldArray(string$) and this loads everything into the FieldArray$() array Is this correct? |
||||
lew247![]() Guru ![]() Joined: 23/12/2015 Location: United KingdomPosts: 1702 |
be back in a min, had a major crash, trying to get it all back again |
||||
![]() ![]() ![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |