Go Down

Topic: [Resolved] VB6 with Uno serialprint to text box (Read 3786 times) previous topic - next topic

backbone

Mar 10, 2012, 09:20 am Last Edit: Mar 27, 2012, 11:49 am by backbone Reason: 1
Hi for those who understand VB6.

I found some code and added it in my project to remotely see some data at the PC

UNO sends:
Code: [Select]
     //send data to serial port for debugging/read data at the PC                      
     Serial.println(sensorValue); //max 3 digits
     Serial.println(brakeValue);   //max 3 digits
     Serial.println(speedcurveValue); //max 3 digits
     Serial.println(brakecurveValue); //max 3 digits
     Serial.println(speedstartValue); //max 3 digits
     Serial.println ("\t"); //use this to indicate end of datastream for next loop to detect
     delay(50);


While reading the data at the PC it needs to check if where to start so the 5 text boxes are filled with the correct values.
If I leave this line out: Serial.println ("\t "); it starts everytime after opening and closing the vb program it writes every time in a different box.
But if I add it it will not read with the below vb code.
So the code should search for the Tab and then display the next cyclus of data and put them in the text boxes.
I have tried numerous things like treshhold higher but I got lost in the things.
Any suggestion would be welcome


Paco

Code: [Select]
Private Sub Form_Load()
 With MSComm1
       If .PortOpen Then .PortOpen = False
       .CommPort = 4
       .Settings = "9600,N,8,1"
       .DTREnable = True
       .RTSEnable = True
       .RThreshold = 1
       .SThreshold = 0
       .PortOpen = True
 End With
 With Text1
   .BackColor = vbWhite
   .Locked = True
   .Text = ""
 End With
End Sub

Private Sub MSComm1_OnComm()

Static Buffer As String
  Buffer = Buffer & MSComm1.Input
  If InStr(Buffer, vbCrLf) Then
     Dim TempBuffer() As String
     TempBuffer = Split(Buffer, vbCrLf)
      If UBound(TempBuffer) >= 5 Then
           Text1.Text = TempBuffer(0)
           Text2.Text = TempBuffer(1)
           Text3.Text = TempBuffer(2)
           Text4.Text = TempBuffer(3)
           Text5.Text = TempBuffer(4)
           Dim I As Integer
           Buffer = ""     'cleanup the Static buffer
           For I = 5 To UBound(TempBuffer) - 1
              'retain any extra data
              Buffer = Buffer & TempBuffer(I)
           Next I
       End If
  End If
End Sub

Never to old to learn and I learn every day

robtillaart


The problem is that with serial data they do not come in all at once.
Every line printed from the Arduino sends an CRLF but your VB code thinks that you have all 5 fields after every CRLF. Read your code to confirm this

So your test should be a test for "\t"  or vbTAB if that exists instead
Code: [Select]

Static Buffer As String
   Buffer = Buffer & MSComm1.Input
   If InStr(Buffer, "\t") Then                        ' if the TAB char found then all 5 fields are in.
      Dim TempBuffer() As String
      TempBuffer = Split(Buffer, vbCrLf)
       If UBound(TempBuffer) >= 5 Then
            Text1.Text = TempBuffer(0)
            Text2.Text = TempBuffer(1)
            Text3.Text = TempBuffer(2)
            Text4.Text = TempBuffer(3)
            Text5.Text = TempBuffer(4)
            Dim I As Integer
            Buffer = ""                                      ' empty the Static buffer
            For I = 5 To UBound(TempBuffer) - 1
               ' retain any extra data
               Buffer = Buffer & TempBuffer(I)
            Next I
        End If
   End If
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

backbone

Hi Rob (Hallo  :P)

Thanks for your answer.

I raised the delay in the UNO from 50 to 200 in the original VB code and it works. :)
I am new to this serial stuff and for the purpose of the program to read the UNO I rather do not want to have any delay.

Is this possible?

I added the Tab just to make sure the difference between CRLF and TAB in VB when you need to search for the start and end of the information which is put in a buffer.
Do not know if this is really needed if I like to speed up things to have real time information gathered from the UNO to the PC program.

Paco

(The Netherlands)
Never to old to learn and I learn every day

backbone

To support what I like to accomplish
http://arduino.cc/forum/index.php/topic,93528.0.html
a screen shot of the simple PC control panel.

Data created or set in the slotrace speed controller need to be changed or read by the PC control program.
The speed and brake graph need to show in future the curve the trigger makes or is set compared to the motion of the speedtrigger.

When that is completed I like to add Bluetooth to the slot race speed controller so we can datalog all data during racing and graph each lap realtime to see where time is lost or to be gained. First PC then Adroid app.

Paco

Never to old to learn and I learn every day

robtillaart


Hoi Paco,

We'll keep the discussion in English (but you can PM me in dutch if you want to).

The Arduino sends the bytes at a certain speed, so it takes (serious) time before they arrive at the PC. You don't need to add the delay in the UNO (unless the transmit buffers overflows)

Increase the serial speed to 115200 as that is 12x as fast as 9600,  (both in VB and Arduino)

Quote
I added the Tab just to make sure the difference between CRLF and TAB in VB when you need to search for the start and end of the information which is put in a buffer.
Do not know if this is really needed if I like to speed up things to have real time information gathered from the UNO to the PC program.


The check for TAB is really needed !! as in your protocol the TAB is a record separator and the CRLF is a field separator.

The arduino sends records with 5 values to the PC. These position of the individual values within the record define their meaning. The values are separated by CRLF and the records are separated by TAB's. If records were separated by CRLF you would never know where a new record starts.

As detecting the TAB separator automatically implies you have at least 5 fields the code does not need to test this.

Code: [Select]

Static Buffer As String
   Buffer = Buffer & MSComm1.Input
   If InStr(Buffer, "\t") Then                        ' if the TAB char found then all 5 fields are in.
      Dim TempBuffer() As String
      TempBuffer = Split(Buffer, vbCrLf)

            Text1.Text = TempBuffer(0)
            Text2.Text = TempBuffer(1)
            Text3.Text = TempBuffer(2)
            Text4.Text = TempBuffer(3)
            Text5.Text = TempBuffer(4)
            Dim I As Integer
            Buffer = ""                                      ' empty the Static buffer
            For I = 5 To UBound(TempBuffer) - 1
               ' retain any extra data
               Buffer = Buffer & TempBuffer(I)
            Next I

   End If

Hopes this helps.
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

backbone

Thanks Rob,

We stay in English here, so more people can learn from my mistakes.  ;)

Upped the speed in UNO and PC to 115200 bps and removed the dealy in the UNO.

Added your code and expanded it a little for more parts of data gathering from the UNO.
I also changed the "\t" to "vbTab" as it did not split the dimbuffer with it as it did not recognized the "\t"

Now I get some runtime error 9 Subscript out of range on for example the temp4 = tempbuffer(3) line.
So I changed the textboxes and read the buffer to a long declared string
Same problem.
I also see in the text boxes when the code stops that there sometimes othe characters in the textbox.
They are shown in the text box as a thick black vertical stripe and in the debug screen as square.

So it looks like the splitting is not quick enough?
Do not know if that causes the script out of range problems as a result.

Code: [Select]
Private Sub MSComm1_OnComm()

Static Buffer As String
Dim temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8 As String

   Buffer = Buffer & MSComm1.Input
   Text9.Text = Buffer                                ' temp Debug window textbox
   If InStr(Buffer, vbTab) Then                        ' if the TAB char found then all 8 fields are in.
      Dim TempBuffer() As String
      TempBuffer = Split(Buffer, vbCrLf)
            temp1 = TempBuffer(0)
            temp2 = TempBuffer(1)
            temp3 = TempBuffer(2)
            temp4 = TempBuffer(3)
            temp5 = TempBuffer(4)
            temp6 = TempBuffer(5)
            temp7 = TempBuffer(6)
            temp8 = TempBuffer(7)
            Text1.Text = temp1
            Text2.Text = temp2
            Text3.Text = temp3
            Text4.Text = temp4
            Text5.Text = temp5
            Text6.Text = temp6
            Text7.Text = temp7
            Text8.Text = temp8
            Dim I As Integer
            Buffer = ""                                      ' empty the Static buffer
            For I = 8 To UBound(TempBuffer) - 1
               ' retain any extra data
               Buffer = Buffer & TempBuffer(I)
            Next I

   End If
End Sub


Never to old to learn and I learn every day

PaulS

Quote
The check for TAB is really needed !! as in your protocol the TAB is a record separator and the CRLF is a field separator.

Which, of course, is quite unusual. Sending value, tab, value, tab, value, tab, value, tab, value, CR, LF would make a lot more sense.

backbone

paulsa

Code: [Select]
      //send data to serial port for debugging/read data at the PC                       
      Serial.print(sensorValue);
      Serial.print("\t");
      Serial.print(speedstartValue);
      Serial.print("\t"); 
      Serial.print(speedcurveValue);
      Serial.print("\t");
      Serial.print(brakeValue);               
      Serial.print("\t");
      Serial.print(brakecurveValue);
      Serial.print("\t");
      Serial.print(sensorMin);
      Serial.print("\t");
      Serial.print(sensorMax);
      Serial.print("\t");
      Serial.println(modelName);
      //delay(500);


So Serial.println is the CRLF?

Then I changed the way of detecting the Tab and CrLf the otherway around but same problem.

Code: [Select]
Private Sub MSComm1_OnComm()

Static Buffer As String
Dim temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8 As Long

   Buffer = Buffer & MSComm1.Input
   Text9.Text = Buffer                                ' temp Debug window textbox
   If InStr(Buffer, vbCrLf) Then                        ' if the TAB char found then all 8 fields are in.
      Dim TempBuffer() As String
      TempBuffer = Split(Buffer, vbTab)
            temp1 = TempBuffer(0) 'speed
            temp2 = TempBuffer(1) 'start speed
            temp3 = TempBuffer(2) 'speed curve
            temp4 = TempBuffer(3) 'brake
            temp5 = TempBuffer(4) 'brake curve
            temp6 = TempBuffer(5) 'modelname
            temp7 = TempBuffer(6) 'sensorMin
            temp8 = TempBuffer(7) 'sensorMax
            Text1.Text = temp1
            Text2.Text = temp2
            Text3.Text = temp3
            Text4.Text = temp4
            Text5.Text = temp5
            Text6.Text = temp6
            Text7.Text = temp7
            Text8.Text = temp8
            Dim I As Integer
            Buffer = ""                                      ' empty the Static buffer
            For I = 8 To UBound(TempBuffer) - 1
               ' retain any extra data
               Buffer = Buffer & TempBuffer(I)
            Next I

   End If
End Sub
Never to old to learn and I learn every day

PaulS

Quote
So Serial.println is the CRLF?

Serial.println() does exactly the same stuff as Serial.print() with the addition that it sends a carriage return and line feed to the serial port, too (after the data it sends).

So, yes, I think that is a better way to send the data.

Code: [Select]
   If InStr(Buffer, vbCrLf) Then                        ' if the TAB char found then all 8 fields are in.
When the code and the comments disagree, the comment doesn't serve much purpose, does it?

So, what IS in buffer when this function returns true?

What is in the TempBuffer elements? Why do you need to when assign those strings to floats, and then assign the floats to text fields? Seems like a lot of overhead when what you want is to get string data from the serial port and display it is string fields on the form.

Code: [Select]
            Buffer = ""                                      ' empty the Static buffer
            For I = 8 To UBound(TempBuffer) - 1
               ' retain any extra data
               Buffer = Buffer & TempBuffer(I)
            Next I

What extra data? What about the tabs that used to separate the fields?

backbone

Paul,

As you see I followed your advise and changed the way UNO sends the data.
Sorry for disagreement is comments. I hope it never happens again. but I cant promiss it.  :smiley-mr-green:

I copied the code from the net and I am slowly adapting it to my needs and maybe others.
I am new to this serial stuff and as I did not wrote this original code it might be that some things are left I do not have the knowledge for now to understand. But I am always willing to learn as I learn every day.

For your question about:
Code: [Select]
Buffer = ""                                      ' empty the Static buffer
            For I = 8 To UBound(TempBuffer) - 1
               ' retain any extra data
               Buffer = Buffer & TempBuffer(I)
            Next I

I have tried to understand it but I do not.
You mean that this is not needed or do I need to change the code in general?


Paco
Never to old to learn and I learn every day

PaulS

The Split command earlier on creates an array of strings, by splitting the specified string at the tabs. If the specified string contains 7 tabs, as yours should, you would get exactly 8 strings in the output array. That bit of code is dealing with the 9th and on substrings. Unless there is an error in communication, you shouldn't need that code.

If there is an error in communication, and there are more than 8 values in the packet, you probably want to discard the whole packet, rather than use the first 8 values on the first pass, and the rest on the next pass (with more added...)

If you are going to keep that code, though, when you re-create the original buffer, minus the first 8 values, you need to put the tabs back between the values as you reassemble the string.

backbone

Paul,

Understand 99% what you explain. Thanks
BTW. If I comment these lines still got the same error.

So what I know and understand.
The oncomm event puts data in the buffer.
When the CRLF is found it stops putting data in the buffer and assuming all 8 value are there due to the Crlf at the end.
Then it sorts the buffer on the tab's and put each value in a textbox.
In the end it clears the buffer.
Start all over again.

Now one thing I might have overlooked in this copied code what if the buffer is not filled from value 1 but starts at value 4 and then the CRLF is received.
This would be a false data assumption.
How does it know all 8 values are in? It only looks at the CrLf assuming all data is in?
Wouldnt it be better to add a start marker (startbit) then the data and then the CrLF (stopbit)
Then only sort the data if the full line from start to stop bit is received.

Paco
Never to old to learn and I learn every day

backbone

I tried some more with the current code and reduced speed to 9600 bps and no delay in the UNO code

I can start the program several times in arow but without unknown cause it hangs with subscript out of range 1 out of 10.
It always happens in the part where the array is splitted by the tab.
When I commented all those except for line one and two there it runs fine.
But the more I ask to be splitted from text3.text the more the program stops.
This looks like a fundemental problem in splitting the array to the textboxes.
When it needs to split it does it correctly and the values go to the correct textbox.

Paco
Never to old to learn and I learn every day

robtillaart

Quote
I also see in the text boxes when the code stops that there sometimes othe characters in the textbox.
They are shown in the text box as a thick black vertical stripe and in the debug screen as square.


Probably VB interpretation of CRLF in a textBox
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

backbone

#14
Mar 11, 2012, 08:15 am Last Edit: Mar 11, 2012, 08:49 am by backbone Reason: 1
More debugging done.

I currently use an other code in VB, Uno still the same 9600 and no delay.
But the eratic problem out out of script stays.
When there is no error the data is in the correct boxes.

Code: [Select]
Private Sub MSComm1_OnComm()

Static strBuffer As String
 With MSComm1
   'test for incoming event
   Select Case .CommEvent
       Case comEvReceive
           '
           ' Something to receive
           ' Receive it and add to our static Buffer
           '
           strInput = .Input
           strBuffer = strBuffer & strInput
           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
                   '
                   ' Yes, there is a complete record
                   ' Extract it from the Buffer and process it
                   '
                   
                   strInput = Mid$(strBuffer, 1, intPos - 1)
                   str = Split(strInput, vbTab)
                   Text9.Text = strInput
                   Text1.Text = str(0)
                   Text2.Text = str(1)
                   Text3.Text = str(2)
                   Text4.Text = str(3)
                   Text5.Text = str(4)
                   Text6.Text = str(5)
                   Text7.Text = str(6)
                   Text8.Text = str(7)
                   '
                   ' 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
 Dim temp As Long

' ARProgressBar1.Value = Text1.Text 'str(0) 'temp2 '150 'str(1)
 
End Sub


Problem I encounter and debug when script out of range appears:
If line Text7.Text = str(6) is out of range it is the str(6) value that causes the problem out of range.
The strBuffer has 17 data blocks which are clearly seperated by single (VBTAB) and double blocks (VBCRLF) .
Now this line should count back for the 8 values needed: strInput = Mid$(strBuffer, 1, intPos - 1)? Or do I misunderstand
The strInput only has 5 values  .....  "-150-1-200-420-0"  .......... the dashes show in VB debugger as a square block.
There should be 8 values?
intPos = 17

str(0) = ""
str(1) = "155"
str(2) = "1"
str(3) = "200"
str(4) = "420"
str(5) = "0"

The 8 data values should be : 11-120-115-155-1-200-420-0
What goes wrong?
Although there are enough datablocks in the buffer the splitter detects less despite the clear difference between vbtab and crlf.
Is it so hard to get some simple plain data (no commas or points) out of the UNO?  :smiley-roll-sweat:

Any suggestion to this bottleneck is appriciated.
Never to old to learn and I learn every day

Go Up