Visual Basic Serial Port Specific Problem

B

Thread Starter

Babbler

<p>...I have checked previous posts and haven't found anything that matches this problem. It is fairly complicated so will try to split it up.

<p>I am programing a Modbus master using VB to communicte with 1 slave. The com port is constantly connected (defined by me) to the slave and I send and receive data using lots of functions.

<p>Although the data stream seems correct (checked using a sniffer), VB seems to be lagging at times and processing a reply to the previous request.

<p>E.g I send "01 04 02 46 00 01 D1 A7", the stream shows the correct reply "01 04 02 00 10 B8 FC", but VB processes the reply to the previous request "01 10 02 00 00 01 00 71".

<p>The input and output buffers are defined local to each function (there are several functions for sending data) so I don't understand how this is possible as theoretically the buffer is 'deleted; as it goes out of scope.

<p>1) Do the buffers need to be global<br>
2) Is data coming in faster than VB can process it and how do I prevent this<br>
3) Do I need to connect and disconnect at the begining and end of each send/receive or is it ok to have the com port constantly connected?<br>
4) Any other ideas??

<p>I do not want to buy a activeX control but would appreciate any other help.

<p>As an example here is a typical function:

<p>Thanks...
<pre>
Private Sub ScanStatus()

MSComm1.Output = Out_Buffer

'TimeOut = 0.05 ' Set wait duration.
Start = Timer ' Set start time.

Do While (Timer < Start + TimeOut ) And _
(MSComm1.InBufferCount < 2 * _
NumberOfDetectorRegisters + 5)

DoEvents

Loop

in_Buffer = MSComm1.Input

DoEvents

Do While Len(In_Buffer) = 0

'there was no reply so try again

For ByteCount = 0 To UBound(Out_Buffer)

txtOutBuffer.Text = txtOutBuffer.Text
& " " & Hex$(Out_Buffer(ByteCount))

Next ByteCount

MSComm1.Output = Out_Buffer

Start = Timer ' Set start time.
Do While (Timer < Start + TimeOut ) And
(MSComm1.InBufferCount < 2 *
NumberOfDetectorRegisters + 5)

DoEvents
Loop

In_Buffer = MSComm1.Input

Loop


'txtInputBuffer.Caption = "

For ByteCount = 1 To Len(In_Buffer)

txtInputBuffer.Text = txtInputBuffer.Text
& " " & Hex$(Asc(Mid$(In_Buffer,
ByteCount, 1)))

If ByteCount > 3 And ByteCount <= (3 +
(NumberOfDetectorRegisters * 2)) Then

'Then process the data here...

next ByteCount

Finish = Timer ' Set end time.

end sub
</pre>
 
Y

Yeasir Rahul

Dear Babbler,

> 1) Do the buffers need to be global <

No.

> 2) Is data coming in faster than VB can process it and how do I prevent this <

Doesn't look like that. In fact I suspect that you've set the time-out too short. So data is coming in _slower_ i.e., it comes actually after VB has timed out.

> 3) Do I need to connect and disconnect at the begining and end of each send/receive or is it ok to have the com port constantly connected? <

It is OK to have the comm control open continuously.

> 4) Any other ideas?? <

Since you have checked the data-stream with a sniffer, and found that the request/response both are OK, I think that the "Settings" property of your MSComm control is OK.

In the code snippet that you attached with the message, the time-out is 0.05 second. Is this value realistic? Could you increase it to something like 1 second?

I think, your system is responding after 0.05 second, and your functions have timed-out by that time, it has not read anything (and has not emptied the buffer). So, the next function is reading the buffer, which is a response to the previous command.

Try to increase the time-out, following the standard of the communication protocol.

Your code snippet has some small inaccuracies. I guess it is not an exact copy of a working code. Variable types are not declared here, and the time-out value is not initialized also (remember, VB will initialize it to zero, which will make the response-reading code ineffective).

> I do not want to buy a activeX control but would appreciate any other help. <

VB and MSComm should be adequate for this application. Third party controls may perform better, and they may be easier to program; but VB can do this job perfectly OK.

BTW, make the "InputLen" property equal to zero; else your read operations may not read the whole buffer in one operation.

Cheers and bet wishes. You can contact me off-list if have problems with my suggestions.

Yeasir Rahul, System Integration Consultant
http:\\www.voltsmith.com
 
I have solved problem 2) Is data coming in faster than VB can process it and how do I prevent this by adding a DoEvents.

One other question though - I seem to need to send 2 requests to get 1 reply (after the first request is sent which only needs to be sent once). Any ideas what the reason for this may be? Is there a chance it may be because I am sending the query too fast after the first reply?

Thanks for any help...
 
I think you can better start to use the MSComm1_OnComm event to read the data from the buffer. This event is triggered once new data has been received on the comport.

==========Read Input buffer==================
Private Sub MSComm1_OnComm()
Dim InString As String

If MSComm1.PortOpen = False Then
MSComm1.PortOpen = True
End If

MSComm1.InputLen = 0
' Check for data.
If MSComm1.InBufferCount Then

InString = MSComm1.Input
txtRead.Text = InString
End If

End Sub

===============send commands===============
This is just a button that I click to send data
=============================================
Private Sub btnSend_Click()

If MSComm1.PortOpen = False Then
MSComm1.PortOpen = True
End If
MSComm1.Output = txtWrite.Text + Chr(13) + Chr(10)
'MSComm1.Output = SendMsgCombo.Item(0) + Chr(13)
'txtWrite.Text = SendMsgCombo.Item(0) + Chr(13)

End Sub
===========================================

Wish this helps, if not i have more examples and information about this subject.
 
T
Check to see if you use the value in a text field. I had a situation with VBA where I read a string of characters from the serial buffer, set it to a variable, then displayed it in a text field. Looking at the variable after it was displayed in a text field, the control characters at the end of the string changed. Don't display values until you are done using them, or assign them to a variable that is only used for the text field.


--
C. Thomas Wiesen
[email protected]
 
Top