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 SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

MSCOMM-multiple cycles

Status
Not open for further replies.

longbeard

Programmer
Aug 4, 2008
6
0
0
US
This is an app for a stationary raster scanner.
Can anyone tell me why the program below cycles thru the OnComm event 2-3 times when starting up or after a bad scan?
Stepping thru from the beginning, before any data is received I can type ? MSCOMM1.CommEvent into the Immediate window and it returns a 3. I haven't scanned anything at this point. It works great on a good read, including the data update, but I want to respond to validation and a bad read appropriately by changing screencolor and text.

Option Explicit
Public prod As String
Public lot As String
Public scan As String
Public conn As ADODB.Connection
Public rs As ADODB.Recordset
Public cmd As ADODB.Command
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Private Sub Form_Load()

Set conn = DataEnvironment1.Connection1
Set rs = DataEnvironment1.rsCommand1

On Error GoTo commerr
With MSComm1
MSComm1.CommPort = 1
MSComm1.PortOpen = True
MSComm1.Handshaking = comRTS
MSComm1.RThreshold = 13
MSComm1.RTSEnable = True
MSComm1.Settings = "9600,E,7,1"
MSComm1.InputLen = 0
End With
commerr:
If Err.Number = 8005 Then
MSComm1.PortOpen = True
Resume Next
End If

End Sub
Private Sub MSComm1_OnComm()
Dim noread As String
noread = "NOREAD"
scan = ""
txtscandata.Text = ""
txtscandata.BackColor = vbWhite
lot = ""
prod = ""
txtdesc.Visible = False
txtdesc.BackColor = vbWhite
txtdesc.Text = ""

Select Case MSComm1.CommEvent
Case comEvReceive
txtscandata.Text = MSComm1.Input
scan = Trim(txtscandata.Text)

If Len(Trim(scan)) >= 13 And InStr(scan, noread) = 0 Then
Call HandleInput
Else
txtscandata.Text = "Bad scan- scan it again!"
txtscandata.BackColor = vbRed
Beep
Beep
Beep
Sleep 4000
GoTo badscan
End If

Case Else
txtscandata.Text = "Ready to Scan"
MSComm1.InBufferCount = 0
Exit Sub
'txtscandata.BackColor = vbRed
'Beep
'Beep
'Beep
' Sleep 4000
End Select

badscan:
MSComm1.InBufferCount = 0
End Sub
Private Sub Form_Unload(Cancel As Integer)
MSComm1.PortOpen = False
End Sub
Public Sub HandleInput()

Dim desc As String
scan = Trim(scan)
prod = Mid(scan, 1, 6)
lot = Mid(scan, 8, 13)
On Error GoTo Errorexit

Set rs = New ADODB.Recordset
Set cmd = New ADODB.Command
Set cmd.ActiveConnection = conn
cmd.CommandType = adCmdStoredProc
cmd.CommandText = "pValidateWSScan"
cmd.Parameters.Append cmd.CreateParameter("@prod", adChar, adParamInput, 10, Trim(prod))
cmd.Parameters.Append cmd.CreateParameter("@lot", adChar, adParamInput, 20, Trim(lot))
cmd.Parameters.Append cmd.CreateParameter("@desc", adChar, adParamOutput, 20, Trim(desc))
cmd.Execute

desc = cmd(2)

If Trim(desc) = "Invalid Product!" Or Trim(desc) = "" Then
txtdesc.BackColor = vbRed
txtdesc.Visible = True
txtdesc.Text = "Invalid Product!"
Beep
Beep
Beep
' Sleep 4000
Set cmd = Nothing
Exit Sub
Else
txtdesc.Visible = True
txtscandata.BackColor = vbGreen
txtdesc.BackColor = vbGreen
txtdesc.Text = desc
Set cmd = Nothing
' Sleep 4000

End If

Errorexit:
If Err.Number = 94 Then
Resume Next
End If

End Sub
'Private Sub OnComm_Idle()
'MSComm1.InBufferCount = 0
'txtscandata.Text = "Ready to Scan"
'scan = ""
'txtscandata.BackColor = vbWhite
'lot = ""
'prod = ""
'txtdesc.Visible = False
'txtdesc.BackColor = vbWhite
'txtdesc.Text = ""
'End Sub


 
Hi,
I've had problems with the Comm port once before and found that by setting all the setting BEFORE opening the comm port solved many issues. Give it a try.
Regards,
Walter
 
Thanx Walter.
Actually, I had resorted to that yesterday for no apparent reason, but it still didn't solve my problem. The behavior in debug mode is different than live. In live mode it seems to cycle thru constantly as if it were polling. In debug, the program stops to wait for initial input. I've moved all the processing except for the .input dump out of the ONComm event. It still cycles thru the Oncomm event twice. This makes it impossible to reset variables since their values change again the second time thru.

Wallace
 
If you send anything and dont read it, this data is stored in a buffer in the OnCom Control. You are probably reading this.
It could be junk created when you turn on the scanner or stuff left over from a bad read nit fully read.

If you only have one read and the data is longer than what you have read (because you read it too fast) it will look like a bad read and the tail of this read could be still in the buffer when you try to read it next.

Whenever there is data in the OnCom receive buffer, the Sub Oncomm should cycle through many times to receive a string.
The number of cycles is more if:-
the string transmitted is longer
the computer is slow or is doing some other task at the instant of transmission
the slower the baud rate
the shorter the time spent or number of statements between the start of the Sub OnComm and the point where you read the buffer.


You should write your routine to take account any possibility by accumulating the data into a buffer before using it.
You have to have some sort of indication that the data string has finished (like a vBCr)
Basically the one way of doing this is-
Eg. MyBuffer = MyBuffer & NewData 'accumulate the data
If Len(MyBuffer)=13 then 'or some other way of detecting a complete data packet
Process the data here
MyBuffer = "" ' Clear buffer for next read
End If
If Len(MyBuffer)>13 then MyIndicateFaultRoutine

OR - if you cant detect the end of the string,

Put a slight delay of a few miliseconds just before the txtscandata.Text = MSComm1.Input statement to allow all data to fill the buffer before reading it. This will however momentarily slightly slow down your application if there are any other events that might be happening at the same time.
 
That probably accounts for why the project behaves differently in RUN verses Debug mode. I'll give this a try. Thanx, TedSmith!

Wallace
 
Also look at setting the receive buffer length to 1.
This causes the Sub ONComm to fire as soon as the buffer is started to fill and makes sure all data is read.
The sub could fire once for every byte sent if the computer is very fast and the baud rate slow but this doesn't really matter at baud speeds.
The example in help shows this.

Also split up the receive into 2 subs so the smaller one with no Dims is the one that repeats itself and the processing is done in another.

Code:
Dim Buffer as String' public declaration

Private Sub MSComm1_OnComm()
'receive data from device. This sub cycles many times each transmission
'uses a small circle that looks like an LED indicators to show if data is received good and is set back to black 1 second later by a timer control
Dim VIDTimeout As Integer
If MSComm1.CommEvent = 2 Then
    shapeVidLED.BackColor = vbGreen
    Buffer = Buffer & MSComm1.Input 'store current contents of comms1 buffer in Buffer1 a few bytes at a time
    If InStr(Buffer, vbCrLf) Then 'my data has a vbCrLf at the end of each transmission
        ProcessVIDData Buffer
    End If
Else
    shapeVidLED.BackColor = vbRed 'garbage - maybe wrong baud rate
End If
End Sub

Sub ProcessVIDData(RxBuffer As String)
'Process Data from loops This sub only fires once each transmission
Dim InData As String
InData1 = RxBuffer
Buffer1 = "" 'Got it all so clear it for next time
If Check1.value=1 then Databox.Caption = Databox.Caption & InData   'show raw data in a label on the screen if checkbox ticked

'Process your data here using  InData

'if data is not valid then make shapeVidLED.backcolor=vbMagenta to show the fact

End Sub
[code\]
 
>look at setting the receive buffer length to 1

I think you mean the receive threshold, RThreshold, rather than the actual buffer length.
 
Thanx, guys. When the HELP said you could set up serial as polling or event-driven, I took that very literally thinking one-scan, one data read. I've also been working without an ETX (CrLf) and basing validation (and scan cycle- I thought) on NOT having a NOREAD and correct length of data. Sounds like that may not be the most accurate way to go. Thanx, again. Wallace
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top