[Resolved] VB6 with Uno serialprint to text box

Rob,

That is an option and I have to look into that how to achieve.
But this basic stuff should work too?
Like said as soon as the program runs OK it is displaying the correct data in the correct boxes.
It hangs on the first or two loops of the splitting.

I downloaded from the MSDN side a oncomm sample.
I ran this to a text box and viewed it a few times after start up.
When the program runs mostly the first 2 lines are missing data.
The first line is never correct.
After this the data looks fine.

So I just thougth of taking out (throw away) the first 3 readings of the oncomm.
I think the splitting and out of range is the due to this start up of the receiving of data in the oncomm event.
Have to see if I can mange this garbage stuff.

Paco

As we have 8 values with 7 tabs extracted from the buffer I like to perform this comparison.

                    strInput = Mid$(strBuffer, 1, intPos - 1)
                    strCheck = InStr(strInput, vbTab)' check if there are enough tabs
                    If strCheck < 7 Then' if we do not have enough tabs
                     'exit loop 'exit the current parsing loop
                    End If

So if we do not have 7 tabs we are sure we do not have all data for one reason or an other so we have to exit the loop and do not need to split the data as this is the cause of the problem.
Why is the exit loop commented? Lack of my ability to code properly :slight_smile:
But it explains what I try to achieve code wise

Paco

The first line is never correct.

So you have discovered that for a good protocol between sender and receiver you not only need field separators and record separators but also a record start character to get synchonization :slight_smile:

Still I propose you change the system that you not wait for 7 or 8 fields but just for a field value pair. This makes it also easier to expand in the future!

I am busy with it.

Paco

Stuck after 2 hours of try and error.

                    strInput = Mid$(strBuffer, 1, intPos - 1)
                    temp1 = InStr(strInput, "A1:") 'gives a position result
                    
                    If temp1 <> 0 Then 'there is a separator in the buffer
                        temp2 = Mid$(strInput, 1, temp1 + 6) 'put A1: seperator and 4 extra characthers in the string
                        temp3 = InStr(temp2, "A1:") 'locate seperator A1:
                        ingLen = Len(temp2) 'measure the length of the whole string
                        'temp4 = Left$(temp2, 1, ((ingLen - temp3)+3)  'remove all left from the seperator A1: and the seperator
                        'check for the first VBtab from the left
                        'remove the VBtab including all to the right
                        'data is left put it in a textbox
                    Else
                        Text1.Text = 0
                    End If

At commented line

'temp4 = Left$(temp2, 1, ((ingLen - temp3)+3)  'remove all left from the seperator A1: and the seperator

I got stuck as the Left$ is not accepted.
The rest of the line is also faulty but I first need the Left$ function to work.
Newbie error?

Paco

                    temp1 = InStr(strInput, "A1:") 'gives a position result

So, why is a position stored in variable named temp1? Why is it not stored in a variable call a1Pos?

                        temp2 = Mid$(strInput, 1, temp1 + 6) 'put A1: seperator and 4 extra characthers in the string

Now we have a variable called temp2, which implies that the variable is the same kind as temp1. Clearly, it isn't. Surely, there is a more meaningful name you could assign to this bit of information.

What type are temp1, temp2, temp3, and temp4?

What problem are you seeing with the temp4 assignment statement?

Paul,

What I first did was write in words what I needed. See the notes behind the lines.
Then I started to code and try and error not knowing what I needed on forehand. Yes now all are called temp but they will be changed if all runs as it should.
Why not now? Just my way of working. New Bie error.

The error that the Left$ gives is Type declaration character does not match declared data type.
Do not shoot me, stary eyes from looking at the monitor for a few hours.

Paco

intPos = InStr(strBuffer, vbCrLf)
                If intPos <> 0 Then
                    '
                    ' Yes, there is a complete record
                    ' Extract it from the Buffer and process it
                    '
                    Dim posA1 As String
                    Dim bufferA1 As String
                    Dim bufferlocA1 As String
                    Dim temp4 As String
                    Dim ingLen As String
                    
                    strInput = Mid$(strBuffer, 1, intPos - 1)
                    posA1 = InStr(strInput, "A1:") 'gives a position result of the requested seperator
                    
                    If posA1 <> 0 Then 'there is a separator in the buffer
                        bufferA1 = Mid$(strInput, 1, posA1 + 6) 'put A1: seperator and 4 extra characthers in the string
                        bufferlocA1 = InStr(bufferA1, "A1:") 'locate seperator A1:
                        ingLen = Len(bufferA1) 'measure the length of the whole string
                        temp4 = Left$(bufferA1, 1, ((ingLen - bufferlocA1) + 3)) 'remove all left from the seperator A1: and the seperator
                        'check for the first VBtab from the left
                        'remove the VBtab including all to the right
                        'data is left put it in a textbox
                    Else
                        Text1.Text = 0
                    End If

Do you see a similarity between these lines:

intPos = InStr(strBuffer, vbCrLf)
posA1 = InStr(strInput, "A1:")

In one case you store the return value in what looks like an int. In the other, you store the return value in a string. Why?

bufferA1 = Mid$(strInput, 1, posA1 + 6)

Now, you are adding 6 to a string. What do you expect the result of that operation to be?

temp4 = Left$(bufferA1, 1, ((ingLen - bufferlocA1) + 3))

Now, here you are subtracting a string from something (an int?) and adding 3 to the result. What is ingLen? Why is it named the way it is? What do you expect to have happen when you subtract a string from it? What type is the result of (ingLen - bufferLocA1)?

Paul,

1] OK, changed posA1 to integer. Do not know how long I can say I am a new bie. :grin:

2]

bufferA1 = Mid$(strInput, 1, posA1 + 6)

The result must contain
A1:XXXVBTAB where xxx is the value I really need. Which can one digit to max 3 digits.
A1:XXVBTAB
A1:XVBTAB
So this means I need at least 7 positions to extract the value I need in longest case A1:123T where T is VBTAB.
From this result which is variable result in length there might be digits in front of the A1: and behind the TAB.
So I have to extract the value from it.
First remove all left of the A1: separator then the seperator itself (can be one action)
Then look for the first tab from the left and remove all on the rigth of the TAB including the TAB itself (can be one action).

3] Here I looked for the LEN and Left$ function
http://www.vb6.us/tutorials/vb6-string-functions
I used this sample

lngLen = Len("Visual Basic")    ' lngLen = 12

So you know where the name came from.

For the LEFT$ function i wanted it to use and see if I could accomplish what I needed.

Paco

I will do more homework.

I think it is time for you to post ALL of your VB app. One thing you should have at the top is Option Explicit which will force you to define the type of every variable that you use. That way, you won't have to post a link and a code snippet to tell me what type a variable is. You will KNOW what type it is.

A useful thing to do is to name variables with the type (or at least a hint as to the type) as part of the name. intPos is good. lngLen is awful, because the type is not implied by the name.

Do not know how long I can say I am a new bie

I presume that you mean you don't know how often you need to say that you are a newbie. I'm trying to help you lose that title. It is not something to be proud of or hung onto tenaciously

If you are now sending name=value data from the Arduino, and I agree that you should, there should be nothing in front of the name or after the value. So, a lot of what you are trying to do is unnecessary. I'd also suggest that tab is not a good end of record marker any more. Get rid of the tab, and use Serial.println() to send the value. Then, in VB look for CR/LF as the end of record marker.

Might I also suggest that none of the values that you were printing were named A1, so making up a name and sending and mapping that name to a field makes no sense. Send the real name. Name the text field in VB to match the name that the value should be stored in.

So, back to the code:

                    Dim bufferlocA1 As String
                    Dim ingLen As String

Neither of these should be String. They should be Integer.

Are you familiar with the F1 key in VB? Position the cursor in a function name, or double click the name to highlight the whole name. Press F1 to get help on the function. The Left function takes a string and a value. The first n characters of the specified string are returned by the Left function, which, given the string and the position of the = or colon (whichever separator you use between the name and value on the Arduino) should be the name. The Right function, with the length of the string minus the same value should give you the value (or maybe len - n - 1; you need to experiment).

Use the name to determine which field to store the value string in.

Paul,

Thank for all the help sofar I really appriciate it.
I followed the advise from Rob and that was I am currently working on.

If I past all code here I get an error message as I am over 9550 characters.

Paco

Paul

Is this what you suggested to be placed in the UNO?

      //send data to serial port for debugging/read data at the PC                       
      Serial.print("sensorValue");Serial.println(sensorValue);
      Serial.print("speedstartValue");Serial.println(speedstartValue);
      Serial.print("speedcurveValue");Serial.println(speedcurveValue);
      Serial.print("brakeValue");Serial.println(brakeValue);
      Serial.print("brakecurve");Serial.println(brakecurveValue);
      Serial.print("sensorMin");Serial.println(sensorMin);
      Serial.print("sensorMax");Serial.println(sensorMax);
      Serial.print("modelName");Serial.println(modelName);

BTW I got the other code working. It hang on the fact the VBTAB was there and was hurting the splitting. As soon as I changed the seperator VBTAB to letter "x" it worked. So you are right vbtab was not the correct seperator at the end of datafield.
Now on to the next challange reading the above values to the text boxes.

Paco

Is this what you suggested to be placed in the UNO?

Something like that, yes. Putting a separator between the name and the value would be helpful.

In the serial monitor this gives the name with the value directly followed.
The previous code only showed the data name.

For my understanding, this is what you ment with a seperator or do you mean the same as a TAB but then an other sign like an X?

 //send data to serial port for debugging/read data at the PC                       
      Serial.print("sensorValue");
      Serial.println(sensorValue);
      Serial.print("speedstartValue");
      Serial.println(speedstartValue);
      Serial.print("speedcurveValue");
      Serial.println(speedcurveValue);
      Serial.print("brakeValue");
      Serial.println(brakeValue);
      Serial.print("brakecurve");
      Serial.println(brakecurveValue);
      Serial.print("sensorMin");
      Serial.println(sensorMin);
      Serial.print("sensorMax");
      Serial.println(sensorMax);
      Serial.print("modelName");
      Serial.println(modelName);

goes in the right direction:

//send data to serial port for debugging/read data at the PC                       
      Serial.print("A,");
      Serial.println(sensorValue);
      Serial.print("B,");
      Serial.println(speedstartValue);
      Serial.print("C,");
      Serial.println(speedcurveValue);
      Serial.print("D,");
      Serial.println(brakeValue);
      Serial.print("E,");
      Serial.println(brakecurveValue);
      Serial.print("F,");
      Serial.println(sensorMin);
      Serial.print("G,");
      Serial.println(sensorMax);
      Serial.print("H,");
      Serial.println(modelName);

this generates something like

A,100
B,120
C,130
etc

Your VB application recognizes the char and map this to the right text field.

Something like this is needed to parse (VB is too long ago)

intPos = InStr(strBuffer, vbCrLf)
If intPos <> 0 Then
  Dim C as Char
  Dim Value as String

  C = strBuffer[0];  'or is it 1 in VB?
  Value = Right$(strBuffer, 2)   'skip the separator

  Select Case(C)
  case A: TextSensorValue.Text = Value
  case B: ...  etc
  End Select
EndIf

Rob,

Are those C or other language?

 Dim C as Char
 C = strBuffer[0];

Paco

Rob,

I managed to distill the value into strValue
The code could be simplified? but it works for me.
I also have the newString containing the letter and seperator with value.
Stuck on the case select.
Watched several sample of case select but cant put my finger on it.

Paco

Private Sub MSComm1_OnComm()
Dim boComplete As Boolean
Dim intPos As Integer
Dim strValue As String
Dim strInput As String
Dim str() As String
Static strBuffer As String
Dim lngPos As Long
Dim lngPos2 As Long
Dim newString As String
Dim lngLen As Long


  
  With MSComm1
    'test for incoming event
    Select Case .CommEvent
        Case comEvReceive ' Something to receive
            strInput = .Input
            'strBuffer = strBuffer & strInput  'Receive it and add to our static Buffer
            strBuffer = strInput  'Receive it and add to our static Buffer
            Do
                '
                ' Check if there's a complete record in the Buffer
                ' NOTE: This code assumes that the sender terminates
                ' each record with a Carriage Return Line Feed Pair
                ' If this is not the case then change vbCrLf below
                ' to whatever the terminator is
                '
                
               intPos = InStr(strBuffer, vbCrLf)
               If intPos <> 0 Then

               lngPos = InStr(strBuffer, vbCrLf) 'catch position number of first CRLF in the buffer
               If lngPos > 0 Then newString = Left$(strBuffer, lngPos - 1) 'If the position is larger then 0 remove all rigth fromt the CRLF
               lngPos2 = InStr(newString, ",") 'catch position number of the comma in the string
               lngLen = Len(newString) 'measure length of string
               If lngPos2 > 0 Then strValue = Right$(newString, (lngLen - 2)) 'remove the letter and the : from the string
               
               Select Case (newString)
               'Case A: TextSensorValue.Text = strValue
               'Case B: TextStartSpeedValue.Text = strValue
               End Select
                                              
                    str = Split(strInput, vbTab) 'debug line
                    Text9.Text = strInput 'debug line
                    
                    ' Check if there's anything else in the Buffer
                    '
                    If intPos + 1 < Len(strBuffer) Then
                        '
                        ' Yes, move it to the front of the Buffer
                        ' and go round the loop again
                        '
                        strBuffer = Mid(strBuffer, intPos + 2)
                    Else
                        '
                        ' Nothing left in the Buffer
                        ' Flush it and signal to exit the loop
                        '
                        strBuffer = ""
                        boComplete = True
                    End If
                Else
                    '
                    ' Haven't got a complete record yet
                    ' exit the loop and wait for the next
                    ' comEvReceive event
                    '
                    boComplete = True
                End If

Have been trying to get the select case to work but I did not succeed with the sample showed by rob.
Workaround made by if statement.
Might be rubbish code but I got it to work.
Now all the text boxes are filled with values.

Option Explicit

Private Sub MSComm1_OnComm()
Dim boComplete As Boolean
Dim intPos As Integer
Dim strValue As String
Dim strInput As String
Dim str() As String
Static strBuffer As String
Dim lngPos As Long
Dim lngPos2 As Long
Dim newString As String
Dim lngLen As Long
Dim strCase As String
 
  With MSComm1
    'test for incoming event
    Select Case .CommEvent
        Case comEvReceive ' Something to receive
            strInput = .Input
            strBuffer = strBuffer & strInput  'Receive it and add to our static Buffer
            Do
                '
                ' Check if there's a complete record in the Buffer
                ' NOTE: This code assumes that the sender terminates
                ' each record with a Carriage Return Line Feed Pair
                ' If this is not the case then change vbCrLf below
                ' to whatever the terminator is
                '
                
               intPos = InStr(strBuffer, vbCrLf)
               If intPos <> 0 Then

               lngPos = InStr(strBuffer, vbCrLf) 'catch position number of first CRLF in the buffer
               If lngPos > 0 Then newString = Left$(strBuffer, lngPos - 1) 'If the position is larger then 0 remove all rigth fromt the CRLF
               lngPos2 = InStr(newString, ",") 'catch position number of the comma in the string
               lngLen = Len(newString) 'measure length of string
               If lngPos2 > 0 Then strValue = Right$(newString, (lngLen - 2)) 'remove the letter and the : from the string
               strCase = Left$(newString, 1)
               
               If strCase = "A" Then TextSensorValue.Text = strValue
               If strCase = "B" Then TextStartSpeedValue.Text = strValue
               If strCase = "C" Then TextSpeedCurveValue.Text = strValue
               If strCase = "D" Then TextBrakeValue.Text = strValue
               If strCase = "E" Then TextBrakeCurveValue.Text = strValue
               If strCase = "F" Then TextSensorMinValue.Text = strValue
               If strCase = "G" Then TextSensorMaxValue.Text = strValue
               If strCase = "H" Then TextModelNumberValue.Text = strValue
                                              
                                        
                    ' Check if there's anything else in the Buffer
                    '
                    If intPos + 1 < Len(strBuffer) Then
                        '
                        ' Yes, move it to the front of the Buffer
                        ' and go round the loop again
                        '
                        strBuffer = Mid(strBuffer, intPos + 2)
                    Else
                        '
                        ' Nothing left in the Buffer
                        ' Flush it and signal to exit the loop
                        '
                        strBuffer = ""
                        boComplete = True
                    End If
                Else
                    '
                    ' Haven't got a complete record yet
                    ' exit the loop and wait for the next
                    ' comEvReceive event
                    '
                    boComplete = True
                End If
            Loop Until boComplete = True
        End Select
  End With 'MSComm1

   
End Sub
               lngPos = InStr(strBuffer, vbCrLf) 'catch position number of first CRLF in the buffer
               If lngPos > 0 Then newString = Left$(strBuffer, lngPos - 1) 'If the position is larger then 0 remove all rigth fromt the CRLF
               lngPos2 = InStr(newString, ",") 'catch position number of the comma in the string
               lngLen = Len(newString) 'measure length of string
               If lngPos2 > 0 Then strValue = Right$(newString, (lngLen - 2)) 'remove the letter and the : from the string

You never modify newString to remove the comma and the stuff that follows it, so newString will still contain something like "A,24" which is not 'A'.

The code in the next post DOES create a new variable that is the stuff before the comma, so a switch/case would work.

Paul,

Thanks for reading and once again for the lessons sofar.

Now I reread again I had a typo and an explanation ommision in that last 2 code lines.

       lngPos = InStr(strBuffer, vbCrLf) 'catch position number of first CRLF in the buffer
               If lngPos > 0 Then newString = Left$(strBuffer, lngPos - 1) 'If the position is larger then 0 remove all rigth fromt the CRLF
               lngPos2 = InStr(newString, ",") 'catch position number of the comma in the string
               lngLen = Len(newString) 'measure length of string
               If lngPos2 > 0 Then strValue = Right$(newString, (lngLen - 2)) 'remove the letter and the "," from the string
               strCase = Left$(newString, 1) 'leave the data only in this string

Ran into an other issue for which I am looking for simple if statement trapping for the first few loops the buffer is filled.
As the value in strCase now sometimes are not only byte values (from 0 to 255) but like "A,0B1" for the first loops I like to make a
if statement that checks if ther are only byte values in strValue otherwise skip.
something like this:

If ((strValue <0) and (>255)) Then
               strValue = vbNullString
               Else
            'RUN code
end if

But the check for 0 to 255 should be in BYTE mode?

Paco