From: Larry Serflaten on

"albertleng" <albertleng(a)gmail.com> wrote

Anyway, in my system, both the normal/alarm message and the device
name are on the same line. How about if normal/alarm message and the
device name are in separate line? How can i effectively process the
message then?

Thanks again, everyone.

----------------

You saw that you had to wait for a specific condition before trying
to process the data. That condition was the vbCrLf that was at the
end of every message. It would be nice if there was an end of
packet signal, if they send the messages on multiple lines, then you
just test for the new condition (end of packet).

If there is no such signal, you'll need to wait until you have all the
reqired information before going off to process the data.

To further my earlier suggestion, I'll defer to Mr. Grier on serial
communications, but I noticed that part of your processing involves
sending a DDE message. I wondered if that DDE may be a problem
while you're in the middle of an OnComm event. What if the
DDE gets tied up, might you loose some data? That is why I
suggested that you send the message to a queue, and process it
later after the OnComm event is allowed to finish.

But, decent testing will show if that is going to be a problem....

Good luck!
LFS


From: Henning on
Be aware that the following could cause loss of data!!

Print #LogFNo, Format(Now, "YYYYYYYY-MM-DD hh:mm:ss") & " " &
"Received = " & MSComm1.Input

Because .Input will empty the uart buffer, a second .Input is not the same
as the first.

If you intend to save only the last .input data do:
Private Sub MSComm1_OnComm()
Dim tmp As String
Static Buffer As String
Dim CrLfPosition As Integer

If MSComm1.CommEvent = comEvReceive Then
tmp = MSComm1.Input
Buffer = Buffer & tmp
Print #LogFNo, Format(Now, "YYYYYYYY-MM-DD hh:mm:ss") & " " &
"Received = " & tmp

If the packet-size is always the same you could set MSComm1.InputLen =
packetsize. Then OnComm will only trigger when packetsize bytes are
received.

/Henning


"albertleng" <albertleng(a)gmail.com> skrev i meddelandet
news:0e024e96-1757-4120-9e22-70a477411802(a)y6g2000pra.googlegroups.com...
Hi all.

Thank you so much. I think your help has helped me to have a big leap
forward in solving my problem.
I have changed my program accordingly as below:


Private Sub MSComm1_OnComm()
Static Buffer As String
Dim CrLfPosition As Integer

If MSComm1.CommEvent = comEvReceive Then
Buffer = Buffer & MSComm1.Input
Print #LogFNo, Format(Now, "YYYYYYYY-MM-DD hh:mm:ss") & " " &
"Received = " & MSComm1.Input
logFLineNo = logFLineNo + 1

CrLfPosition = InStr(Buffer, vbCrLf)
If CrLfPosition > 0 Then
tTerminal.Text = Buffer
ListMessage.AddItem Format(Now, "YYYYYYYY-MM-DD hh:mm:ss") & "
" & " Received " & Buffer, ListMessage.ListCount
Print #LogFNo, Format(Now, "YYYYYYYY-MM-DD hh:mm:ss") & " " &
"Received = " & MSComm1.Input
logFLineNo = logFLineNo + 1


Dim Temp As String
Temp = Mid$(Buffer, 1, CrLfPosition - 1)
Call ProcessFASMessage(Temp)
Buffer = Mid$(Buffer, CrLfPosition + 1)
End If
End If

End Sub

Private Sub ProcessFASMessage(Temp As String)
Dim j As Integer

'There are 3 alarmMsgs and 3 normalMsgs in this system.
'PointAddress is the device name
If (InStr(Temp, alarmMsg1) > 0) Or (InStr(Temp, alarmMsg2) > 0) Or _
(InStr(Temp, alarmMsg3) > 0) Then
For j = 1 To totalPoint
If InStr(Temp, PointAddress(j)) > 0 Then
txtPoint(j).Text = "1"
txtPoint(j).LinkMode = vbLinkManual
txtPoint(j).LinkPoke
ListMessage.AddItem Format(Now, "YYYYYYYY-MM-DD hh:mm:ss")
& " " & " Send " & txtPoint(j).Text _
& " to " & txtPoint(j).LinkItem, ListMessage.ListCount
Print #LogFNo, Format(Now, "YYYYYYYY-MM-DD hh:mm:ss") & "
" & " Send " & txtPoint(j).Text _
& " to " & txtPoint(j).LinkItem
logFLineNo = logFLineNo + 1
End If
Next j
ElseIf (InStr(Temp, normalMsg1) > 0) Or (InStr(Temp, normalMsg2) > 0)
Or _
(InStr(Temp, normalMsg3) > 0) Then
For j = 1 To totalPoint
If InStr(Temp, PointAddress(j)) > 0 Then
txtPoint(j).Text = "0"
txtPoint(j).LinkMode = vbLinkManual
txtPoint(j).LinkPoke
ListMessage.AddItem Format(Now, "YYYYYYYY-MM-DD hh:mm:ss")
& " " & " Send " & txtPoint(j).Text _
& " to " & txtPoint(j).LinkItem, ListMessage.ListCount
Print #LogFNo, Format(Now, "YYYYYYYY-MM-DD hh:mm:ss") & "
" & " Send " & txtPoint(j).Text _
& " to " & txtPoint(j).LinkItem
logFLineNo = logFLineNo + 1
End If
Next j
End If

End Sub

I don't have access to site at the moment and my testing is done using
virtual serial port downloaded from
http://www.eterlogic.com/downloads/SetupVSPE.zip
I'll need my people on site to test it out and let me know the
outcome.

Anyway, in my system, both the normal/alarm message and the device
name are on the same line. How about if normal/alarm message and the
device name are in separate line? How can i effectively process the
message then?

Thanks again, everyone.



On Jun 18, 6:49 am, "Larry Serflaten" <serfla...(a)gmail.com> wrote:
> "albertleng" <albertl...(a)gmail.com> wrote
>
> > 2) If I can solve the first issue, please suggest to me the most
> > efficient way to process the chunk of data received by my program.
>
> As you have read, others have suggested that you need to add what you
> get from the connection to what has already arrived, and then parse that
> for an end of line sequence. eg: (From Mr. Grier's reply)
>
> Buffer = Buffer & MSComm1.Input
> CrLfPosition = InStr(Buffer, vbCrLf)
> If CrLfPostion > 0 Then
> Dim Temp As String
> Temp = Mid$(Buffer, 1, CrLfPosition -1)
> Process(Temp) 'you write this code<<< - Temp contains a full line
> Buffer = Mid$(Buffer, CrLfPosition +1) 'this is important! clean-up
> required
> End If
>
> I wanted to suggest that you avoid processing the input from the OnComm
> event.
> Instead of processing it then and there, add the recieved line to a
> collection (a queue)
> and enable a timer:
>
> ...
> Temp = Mid$(Buffer, 1, CrLfPosition -1)
> RcvQue.Add Temp
> ProcessTimer.Enable
> Buffer = Mid$(Buffer, CrLfPosition +1) 'this is important! clean-up
> required
> ...
>
> When the timer fires, then call your process routine:
>
> Private Sub ProcessTimer_Timer()
> If RcvQue.Count > 0 Then
> Process RcvQue(1)
> RcvQue.Remove 1
> Else
> ProcessTimer.Enabled = False
> End If
> End Sub
>
> That way, you get in and get out of the OnComm event quickly, always
> a good idea when talking with the outside world.
>
> As far as actually doing the string manipulations and other work, That
> would
> best be handled in another thread, once you get the communication up and
> working. It seemed to me you were checking Terminal.Text quite often and
> should have really assigned the needed portion to a string for processing.
> But first, see if you can get your complete messages working, then post
> again
> to clean up the processing code....
>
> LFS


From: Dee Earley on
On 20/06/2010 15:36, albertleng wrote:
> Hi all.
>
> Thank you so much. I think your help has helped me to have a big leap
> forward in solving my problem.
> I have changed my program accordingly as below:
>
>
> Private Sub MSComm1_OnComm()
> Static Buffer As String
> Dim CrLfPosition As Integer
>
> If MSComm1.CommEvent = comEvReceive Then
> Buffer = Buffer& MSComm1.Input
> Print #LogFNo, Format(Now, "YYYYYYYY-MM-DD hh:mm:ss")& " "&
> "Received = "& MSComm1.Input
> logFLineNo = logFLineNo + 1
>
> CrLfPosition = InStr(Buffer, vbCrLf)
> If CrLfPosition> 0 Then

Note that you should still do this final check in a loop until there are
no more delimiters.
If you receive more then two full delimited messages on any one event,
you will be processing one message behind from that point onwards.
If it happens again, you will be 2 behind, etc..

Whether this is a huge problem or a small one depends on the frequency
of the data being received.

--
Dee Earley (dee.earley(a)icode.co.uk)
i-Catcher Development Team

iCode Systems

(Replies direct to my email address will be ignored.
Please reply to the group.)