Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

MSComm losing characters

Status
Not open for further replies.

KornGeek

Programmer
Aug 1, 2002
1,961
US
I have a program that communicates with a device over the serial port, and I am using the MSComm control to handle this. Everything seems to be working fine most of the time.

The issue is that if the user has a window open (we did this with Internet Explorer) and not maximized, and then the user clicks the scroll bar at the right time, several of the characters being transmitted are not received, and a few others are corrupted (received as "?" character). This is easily reproduceable and not a fluke.

I can reduce (but not completely eliminate) the occurrence of this by changing the priority of my program to High, but this hogs CPU processing time, and makes it almost impossible to run other programs. It seems as if the scrolling action is causing Windows to not pull characters out of the UART in a timely fashion.

The data is 130 characters transmitted at 9600 baud. I've had as little as about 110 characters successfully transmitted with the missing and corrupted characters occurring randomly in the string.

Below is a sample of my code. I use the DoEvents function to release control back to Windows to handle things such as minimizing or restoring my program, or handling other programs. Although I want to protect my data, I don't want to keep them from using their computer. Here is some sample code:


Public Function CheckForData(ByRef timeout as Boolean) As String
On Error GoTo CheckForDataErr

Dim gotdata As Boolean
Dim t1 As Double
Dim t2 As Double

gotdata = False
timeout = False
t1 = Timer
t2 = READTIMEOUT + t1
While (gotdata = False) And (timeout = False)
If MyForm.comPort.InBufferCount = EXPECTEDDATASIZE Then
MyForm.comPort.InputLen = 0
gotdata = True
End If
End If
If gotdata = False Then
t1 = Timer
If t1 > t2 Then
timeout = True
End If
DoEvents
End If
Wend
CheckForData = MyForm.comPort.Input
Exit Function

CheckForDataErr:
HandleError Err.Number, Err.Description, AppTitle
Resume Next

End Function


The way I am currently doing it, I am using a specified READTIMEOUT constant as the maximum length of time to wait (currently set to 10 seconds). In my loop, I'm checking to see if all of the data is there. If it's not there, I'm checking the current time to see if we have timed out. I then allow Windows to do what it needs to, and restart the loop.

I appreciate any advice you can give on how I might better handle this.
 
Can't see why its doing it. I've never had a com program have this kind of problem. Although I always use the commevent to get the data from the port.

You have 2 End If statements in a row at one point in the code. Is this a typo? Because I do not see the corresponding IF - THEN statement.

While (gotdata = False) And (timeout = False)
If MyForm.comPort.InBufferCount = EXPECTEDDATASIZE Then
MyForm.comPort.InputLen = 0
gotdata = True
End If
End If < ------------ This one here
If gotdata = False Then



Also, what kind of handshaking are you using with your device that you are communicating with? It's possible that it might be sending a character and the COM port is not ready to receive it because of you scrolling the window. if there is no handshaking, then the data could get corrupted here.

I would probably put some sort of exit in your first part of the loop:

If MyForm.comPort.InBufferCount = EXPECTEDDATASIZE Then
MyForm.comPort.InputLen = 0
gotdata = True
' exit loop here
End If

This way you don't have to wait for the timeout = true to finish your loop. Why wait if you have gotten the data?

Hope this helps,

Robert
 
like i said i had the same problem using doevents inside a loop. and my app was maximized and the user could do nothing but use my menu and it lost chars when user did nothing. what did improve it though is i was originally setting a flag inside the OnComm sub and checking for it in my loop. i changed that to check if the input buffer was empty instead and it worked much better.
 
Do While frmJAE.MSComm1.InBufferCount = 0
DoEvents 'dont hog the resources
Loop
 
TheVampire,
You are correct that the extra End If was a typo. My apologies.

I'm not using any real handshaking. I'm simply sending one character out, and then waiting to see if I get a response. I purge the buffer before sending then trigger character, and the above code is my routine for checking for data.

Even if I started using the comm event, I don't think that would make a significant difference, because the data itself is corrupted before I ever see it.
 
TheVampire,
after re-reading your post, I think I better understand what you are saying. I'm not sure what kind of handshaking I can implement (if any) because I have no control over what the device on the other end does.

Do you have any suggestions of how I could accomplish this?

Thank you.
 
Well, if you don't have any control over the device, and it does not have handshaking, then there's not much you can do there. It's just going to spit the data at you and hope you can catch it. A &quot;Fire and Forget&quot; sort of thing...

One other thing. What do you have the InputBufferSize set to on the com port control? Is it the default ( 512 bytes, I think ) or did you change that?

Robert
 
I do not explicitly set the InputBufferSize, so I believe it would still be set to the default value.

Would it be better to set this to some value? In this program, I am expecting 130 characters max. If the buffer were not flushed before asking for more data, there could be worst case about 150 characters max. Does it hurt to have the InputBufferSize set to so much larger than I am expecting?

Thank you for all of your help in this matter.
 
Using a larger buffer size does increase the memory that your application uses, but it would have to be pretty large to effect it really, with the size of memory on most PC's these days.

If you are only catching 130 characters, then the default setting of 512 should be fine.

Does your problem happen on any machine you try it on? Have you tried a different com port on the same machine? I've seen quite a few messed up com ports in my time, including ones that worked intermittantly. You might have an actual hardware problem.

Robert
 
Korngeek

if there is no handshaking and no flow control there is NOTHING yo can do to prevente the spliting of data will ocurr. This does not mean that the data itself is corrupted, but that the com port is not &quot;recognizing&quot; the start of it.

Have you tried with setting the buffer size to the max lenght of the string outputed by the device ? and..
have you tried to close the commport after the comevent event ?
I mean, something like:
(inside de mscomm commevent)

if msc.commevent=2 then
data=msc.input
msc.portopen=false
msc.portopen=true.
end if



Linux Spoken
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top