Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 09:21 13 May 2025 Privacy Policy
Jump to

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 : Newie got a few questions

     Page 5 of 25    
Author Message
MikeO
Senior Member

Joined: 11/09/2011
Location: Australia
Posts: 275
Posted: 01:09am 29 Aug 2016
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 1702
Posted: 02:22am 30 Aug 2016
Copy link to clipboard 
Print this post

  MikeO said   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.


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 programEdited by lew247 2016-08-31
 
MicroBlocks

Guru

Joined: 12/05/2012
Location: Thailand
Posts: 2209
Posted: 06:15am 30 Aug 2016
Copy link to clipboard 
Print this post

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]


Edited by MicroBlocks 2016-08-31
Microblocks. Build with logic.
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1702
Posted: 06:48am 30 Aug 2016
Copy link to clipboard 
Print this post

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: Thailand
Posts: 2209
Posted: 09:17am 30 Aug 2016
Copy link to clipboard 
Print this post

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: Australia
Posts: 1667
Posted: 11:19am 30 Aug 2016
Copy link to clipboard 
Print this post

  lew247 said  
BUT
Unfortunately I cannot understand a lot of it

'IS this the function name? not sure what s$, FieldNumber,d$ means??


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
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 Kingdom
Posts: 1702
Posted: 10:22pm 30 Aug 2016
Copy link to clipboard 
Print this post

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)
Edited by lew247 2016-09-01
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 3999
Posted: 10:38pm 30 Aug 2016
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 1702
Posted: 10:44pm 30 Aug 2016
Copy link to clipboard 
Print this post

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 workEdited by lew247 2016-09-01
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 3999
Posted: 11:53pm 30 Aug 2016
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 1702
Posted: 12:08am 31 Aug 2016
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 2927
Posted: 12:14am 31 Aug 2016
Copy link to clipboard 
Print this post

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.

Edited by WhiteWizzard 2016-09-01
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2927
Posted: 12:20am 31 Aug 2016
Copy link to clipboard 
Print this post

Im just checking: Did you need PRINT FieldArray$(25) as opposed to Print GetFieldArray$(25)?
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1702
Posted: 12:22am 31 Aug 2016
Copy link to clipboard 
Print this post

Nice try Phil
I removed the AS INTEGER but it still throws the same error
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1702
Posted: 12:25am 31 Aug 2016
Copy link to clipboard 
Print this post

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 Edited by lew247 2016-09-01
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2927
Posted: 12:30am 31 Aug 2016
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 2927
Posted: 12:32am 31 Aug 2016
Copy link to clipboard 
Print this post

Before I fire things up, what happens when you type: PRINT FieldArray$(25)

 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1702
Posted: 12:34am 31 Aug 2016
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 2927
Posted: 12:37am 31 Aug 2016
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 1702
Posted: 12:44am 31 Aug 2016
Copy link to clipboard 
Print this post

be back in a min, had a major crash, trying to get it all back again
 
     Page 5 of 25    
Print this page
The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025