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?
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
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)?
1] OK, changed posA1 to integer. Do not know how long I can say I am a new bie.
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).
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.
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.
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);
//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
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.
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?
I kow it is not correct in code but did not know how to describe it in code .
So in words what I tried to accomplish:
If the value inside strValue is not a chrachter from 0 to 255 and nothing else like comma, letters or other charchaters then.........
Had some help from an other VB forum to get things done.
The VB code is below.
Now need to work on the code to send the data back to the UNO if it is changed in the PC control panel.
So the display on the UNO displays the same data as the PC control panel and vice versa.
Private Sub MSComm1_OnComm()
Static strBuffer As String
Static boSync As Boolean
Dim strData As String
Dim strRec As String
Dim intPos As Integer
Dim boComplete As Boolean
With MSComm1
Select Case .CommEvent
Case comEvReceive
strData = .Input
strBuffer = strBuffer & strData
Do
intPos = InStr(strBuffer, vbCrLf)
If intPos > 0 Then
strRec = Mid$(strBuffer, 1, intPos - 1)
'
' Have we synchronised yet ?
'
If Not boSync Then
'
' Ignore everything until a "A" record is received
' Once it has been, then set the synchronised flag
' and start processing
'
If Mid$(strRec, 1, 1) = "A" Then
boSync = True
Call ProcessRecord(strRec)
End If
Else
'
' We are synchronised so process the data received
'
Call ProcessRecord(strRec)
Label12.Caption = "Syncronized"
Label12.ForeColor = vbBlack
End If
If Len(strBuffer) > intPos + 1 Then
strBuffer = Mid(strBuffer, intPos + 2)
Else
strBuffer = ""
boComplete = True
End If
Else
boComplete = True
End If
Loop Until boComplete = True
End Select
End With
End Sub
Private Sub ProcessRecord(strRec As String)
'
' StrRec is expected to be:
' Single Alphabetic character between A and K (inclusive, excluding I)
' followed by a comma
' followed by a number between 0 and 255 (inclusive)
' eg
' A,120
'
Dim strParts() As String
Dim strValue As String
Dim intI As Integer
Dim boError As Boolean
intI = 1
'
' Ignore null records
'
If strRec <> vbNullString Then
strParts = Split(strRec, ",")
'
' Check that there's two values
'
If UBound(strParts) = 1 Then
'
' Check that the second value is numeric
'
Do
If Mid$(strParts(1), intI, 1) < "0" Or Mid$(strParts(1), intI, 1) > "9" Then
boError = True
Else
intI = intI + 1
End If
Loop Until boError Or intI > Len(strParts(1))
If Not boError Then
'
' Second value is numeric check it's in the correct range
'
If CInt(strParts(1)) >= 0 And CInt(strParts(1)) <= 1024 Then
strValue = strParts(1)
'
' Set the appropriate TextBox to the value sent
'
Select Case strParts(0)
Case "A"
TextSensorValue.Text = strValue
Case "B"
TextStartSpeedValue.Text = strValue
Case "C"
TextSpeedCurveValue.Text = strValue
Case "D"
TextBrakeValue.Text = strValue
Case "E"
TextBrakeCurveValue.Text = strValue
Case "F"
TextSensorMinValue.Text = strValue
Case "G"
TextSensorMaxValue.Text = strValue
Case "H"
TextModelNumberValue.Text = strValue
Case "J"
TextSpeedValue.Text = strValue
Case "K"
TextDeathBandValue.Text = strValue
Case Else
'
' Unrecognised Letter
'
Debug.Print "Invalid Code Received: " & strRec, , "Process Record"
End Select
Else
'
' Value is out of range
'
Debug.Print "Value Received is out of range: " & strRec, , "Process Record"
End If
Else
'
' Value is non-numeric
'
Debug.Print "Non-Numeric Value Received: " & strRec, , "Process Record"
End If
Else
'
' Less than or more than two items in the data
'
'MsgBox "Invalid Record Format: " & strRec, , "Process Record"
Debug.Print "Invalid Record Format: " & strRec, , "Process Record"
End If
End If
'send the data to a progressbar
ARProgressBar1.Value = TextSpeedValue.Text
ARProgressBar2.Value = TextStartSpeedValue.Text
ARProgressBar3.Value = TextSpeedCurveValue.Text
ARProgressBar4.Value = TextBrakeValue.Text
ARProgressBar5.Value = TextBrakeCurveValue.Text
ARProgressBar6.Value = TextSensorValue.Text
End Sub