From: Larry Serflaten on 20 Jun 2010 12:45 "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 20 Jun 2010 17:18 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 22 Jun 2010 04:39 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.)
First
|
Prev
|
Pages: 1 2 Prev: Clear debug window Next: I need to convert hex colors from Photoshop to something usable inGDI |