dcsimg
Results 1 to 18 of 18

Thread: Missing data from RS232

  1. #1

    Thread Starter
    Member
    Join Date
    May 2012
    Posts
    51

    Missing data from RS232

    hi ,

    I have a code as below. It receive data from PLC machine through rs232. This machine have 3 stations that will be sending out data once testing completed. all the 3 station will be tested simultaneously or 1 by 1.

    It was working fine until I notice that recently i have missing data. Assume that i supposed to receive 100 data but receive only about 90% of it. Any idea how i can prevent from missing data when receiving ?



    Code:
    Private Sub MSComm1_OnComm()
        Dim i           As Long
        Dim strInput    As String
        Dim strEnd      As String
        Dim strNow      As String
    
        i = 0
        strInput = ""
        strNow = ""
        Label7.Caption = ""
        Label7.BackColor = vbYellow
    
        strTerminalCharacter = vbCrLf
    
        Do
            strInput = strInput & MSComm1.Input
            DoEvents
            i = i + 1
            strEnd = Right(strInput, 2)    'Incase want to check Terminal Characters
            Text3.Text = i
            If MSComm1.PortOpen Then Shape1.BackColor = vbGreen Else Shape1.BackColor = vbRed
            DoEvents
        Loop Until (i > 3000) Or (strEnd = strTerminalCharacter)
    
        If (Len(strInput) >= nTotalLengthReceive) And (strEnd = strTerminalCharacter) Then
            If (List1.ListCount >= nAutoSaveData) Then Call Command2_Click  'Auto save data after how many scan
            Text1.Text = Left(strInput, nDataLength)
            Label7.Caption = Left(strInput, nDataLength)
            If Check1.Value = 1 Then
                Clipboard.Clear
                Clipboard.SetText (Label7.Caption)
            End If

  2. #2
    PowerPoster
    Join Date
    Feb 2012
    Location
    West Virginia
    Posts
    13,030

    Re: Missing data from RS232

    I see a few possible issues.
    Your event does not check to see if the event was fired by a receive event which could cause your program to hang
    Looping within the receive event is not really a good idea and combined with the issue above could cause your program to hang.
    You are trimming data based on nDataLength but it is not set in the routine so if your data is longer than this value you are going to be discarding the remaining data.

  3. #3

    Thread Starter
    Member
    Join Date
    May 2012
    Posts
    51

    Re: Missing data from RS232

    Hi datamiser thanks for the reply.
    The reason I'm using nDataLength coz that's the length of data I'm going to receive from the station. Tested them with 3rd party software.
    How do I check to see if the event was fired & remove looping ? Any guides ? Thanks

  4. #4
    PowerPoster
    Join Date
    Feb 2012
    Location
    West Virginia
    Posts
    13,030

    Re: Missing data from RS232

    I would suggest looking at the online help file. There is an example there of how to use the On Comm event.

  5. #5

    Thread Starter
    Member
    Join Date
    May 2012
    Posts
    51

    Unhappy Re: Missing data from RS232


    Code:
    Private Sub MSComm1_OnComm()
        Dim i           As Long
        Dim strInput    As String
        Dim strEnd      As String
        Dim strNow      As String
        
      ''----------------------------------------------------------------
        i = 0
        strInput = ""
        strNow = ""
        Label7.Caption = ""
        Label7.BackColor = vbYellow
        strTerminalCharacter = vbCrLf
      ''----------------------------------------------------------------
       Do
            strInput = strInput & MSComm1.Input
            DoEvents
            i = i + 1
            strEnd = Right(strInput, 2)    'Incase want to check Terminal Characters
            Text3.Text = i
            If MSComm1.PortOpen Then Shape1.BackColor = vbGreen Else Shape1.BackColor = vbRed
            DoEvents
        Loop Until (i > 3001) Or (strEnd = strTerminalCharacter)
        ''----------------------------------------------------------------
          
        If (Len(strInput) >= nTotalLengthReceive) And (strEnd = strTerminalCharacter) Then
        If (List1.ListCount >= nAutoSaveData) Then Call Command2_Click  'Auto save data after how many scan
     
            Text1.Text = Left(strInput, nDataLength)
         
             If Check1.Value = 1 Then
                Clipboard.Clear
                Clipboard.SetText (Label7.Caption)
            End If
        ''----------------------------------------------------------------


    any other suggestion to prevent from missing data ? still trying to figure it out. Any helps ?
    thanks

  6. #6
    PowerPoster
    Join Date
    Jul 2006
    Location
    Maldon, Essex. UK
    Posts
    6,334

    Re: Missing data from RS232

    I'd remove the 'DoEvents' as that could cause re-entry into the OnCom event which could possibly cause data loss. I'd replace it with 'Shape1.Refresh'

  7. #7

    Thread Starter
    Member
    Join Date
    May 2012
    Posts
    51

    Question Re: Missing data from RS232

    Quote Originally Posted by Doogle View Post
    I'd remove the 'DoEvents' as that could cause re-entry into the OnCom event which could possibly cause data loss. I'd replace it with 'Shape1.Refresh'
    Hi doogle,
    How to replace it ?

  8. #8
    PowerPoster
    Join Date
    Jul 2006
    Location
    Maldon, Essex. UK
    Posts
    6,334

    Re: Missing data from RS232

    Change:
    Code:
            If MSComm1.PortOpen Then Shape1.BackColor = vbGreen Else Shape1.BackColor = vbRed
            DoEvents
    to:
    Code:
            If MSComm1.PortOpen Then Shape1.BackColor = vbGreen Else Shape1.BackColor = vbRed
            Shape1.Refresh

  9. #9
    Fanatic Member
    Join Date
    Mar 2009
    Posts
    739

    Re: Missing data from RS232

    I dont know if the Form UI will refresh while your code is looping so Refresh might not work unless you call doevents. Either way, your loops will make your application UI very unresponsive unless you call DoEvents.

    But the looping doevents is certainly causing your data loss (ReEntrant OnComm)

    If you really want to keep the doevents then at least do this.

    '//The very first line of code inside the OnComm
    MSComm1.RThreshold = 0


    '//Then the very last line of the oncomm event
    MSComm1.RThreshold = 1


    That will Simply prevent reentrant oncomm events

    It's been a while since i worked with mscomm1 so i cant quite remember if you're allowed to change rthreshold while the port is open. Also, i notice in your code that youre not checking to see what type of event occured. You could be getting changes is flow control or errors which will still appear as reentrant oncomm events. So, here is another method.

    '// Very top of the form code outside of the oncomm
    Dim OnCommIsRunning As Boolean
    '// we'll use this as a Mutex Flag

    '//Then the first two lines inside the OnComm:-
    If OnCommIsRunning = True then Exit sub
    OnCommIsRunning = True


    '//The very last line of the OnComm:-
    OnCommIsRunning = False


    Using that method the ReEntrant oncomms will still be firing they just wont be interferring with the port.
    Last edited by IanS; Jun 1st, 2013 at 02:29 AM.

  10. #10
    PowerPoster
    Join Date
    Feb 2012
    Location
    West Virginia
    Posts
    13,030

    Re: Missing data from RS232

    The refresh method should refresh the display without needing a doevents. I used this method in many projects to update the display on a label or a progressbar no problems.

  11. #11
    PowerPoster
    Join Date
    Jul 2006
    Location
    Maldon, Essex. UK
    Posts
    6,334

    Re: Missing data from RS232

    Having looked at your code again I can see another area where things may go astray.

    It looks as if you want to buffer the data until either your receive a vbCrLf ('Terminal Character') or you've looped more than 3001 times.
    I'm not sure what you're really trying to do but I suspect you may have fallen into the common 'trap' of thinking that if RThreshold = 1 then you will read only 1 character when you issue the .Input method. This is not necessarily the case. The OnCom event is triggered when there are at least RThreshold number of bytes available to be read - there may be more than 1. If 'i' is meant to be keeping a count of the number of characters received then it's likely to be inaccurate.

    This also compromises the method you are using to 'save' the 'Terminal Character'. For example, consider the following:

    OnCom event n: data received = abcdvbCr -> strinput = "abcdvbCr"
    OnCom event n+1: data received = vbLfefg -> strinput = "abcdvbCrvbLfefg"

    when you execute the 'Right(strInput, 2)' it will return 'fg' and you will have missed the vbCrLf. When you do eventually exit the loop the statement
    Code:
    If (Len(strInput) >= nTotalLengthReceive) And (strEnd = strTerminalCharacter) Then
    will return False since strEnd will not equal strTermnalCharacter.

    What is the significance of the '3001' condition in the loop ? How does it relate to the contents of nTotalLengthReceived ?

    (I also noticed another DoEvents statement, which should be removed)
    Last edited by Doogle; Jun 1st, 2013 at 11:10 PM.

  12. #12
    Fanatic Member
    Join Date
    Mar 2009
    Posts
    739

    Re: Missing data from RS232

    We dont know what his InputLen is. We dont know if his RThreshold is 1 or above. I'm assuming they're both set ok because he says he losses only 10% of his data. Personally I'm surprised he's not lossing 90%

    He needs the doevents otherwise his application UI is going to be very unresponsive. Maybe it's just a monitoring app
    Ication where a user just watches in which case a clunky UI won't matter.

    But in order to debug his code properly we'd need a description of the data he expects.

    But honestly, the code is so bad that it just can't be fixed. It needs throwing away and starting over.

  13. #13
    PowerPoster
    Join Date
    Jul 2006
    Location
    Maldon, Essex. UK
    Posts
    6,334

    Re: Missing data from RS232

    Quote Originally Posted by IanS View Post
    He needs the doevents otherwise his application UI is going to be very unresponsive.
    Doubt it. With the loop exiting after receiving a maximum of 3001 that's just 3 seconds at 9600 baud. I suspect the loop really exits much more frequently.

    DoEvents in asynchronous operations is just asking for trouble and in 99.999999% of the time is not required. The .Refresh methods of controls will always work when in a loop like OPs.

    If the PLC machines are blasting data at very high rates it may be better to change from an event driven model to Polling using a Timer. That way the programmer is 'in charge' rather than the connected devices.

  14. #14
    Fanatic Member
    Join Date
    Mar 2009
    Posts
    739

    Re: Missing data from RS232

    We dont know what his InputLen is. We dont know if his RThreshold is 1 or above. He says he losses only 10% of his data. Personally I'm surprised he's not lossing 90%

    He needs the doevents otherwise his application UI is going to be very unresponsive.

    In order to make a proper assessment we'd need a description of the data he expects. Maybe then his code could be bodged a little to reduce the data loss

    But in all honesty it needs throwing away and starting over

  15. #15
    PowerPoster
    Join Date
    Feb 2006
    Posts
    20,850

    Re: Missing data from RS232

    I'd agree that code is quite a mess. The point of the OnComm event precludes its handler containing a loop that does multiple .Input fetches. That's probably why at least one of the DoEvents was jammed in there. And testing for .Open inside OnComm seems a bit bizarre to me.


    I don't see how using a polling loop is going to yield better performance than using OnComm properly. That approach is rife with warts and pitfalls.

    You'd probably want to set .InputLen to a somewhat larger value than the default and then set .RTheshold to a substantial portion of that.

    Of course the flaw in this is that an .RThreshold > 1 means your application must be able to rely on fixed length messaging. Not just be based on fixed length messages but also to assume that no chars can ever be lost.

    The reason for this can be seen with a simple case.

    Say .RThreshold = 10, but the remote end can send "messages" of 1 to 20 characters plus a CR terminator. If you start up and the remote end sends just one message of 5 characters (total of 6 sent and received) then OnComm will never be triggered for comEvReceive so you would never read the .Input data.

    What you really want is "magic" where OnComm gets triggered by receipt of your delimiter, but that doesn't exist.

    Barring that you want a "timeout" where if there is data buffered but less than .RThreshold chars are there you want OnComm triggered after some small (but not too small) time limit elapses, so you can drain what is there and process it.

    We don't have that either, but you can simulate it using a Timer control. In the Timer event handler you can test for .InBufferCount > 0 and if True then you'd grab and process the available data.

    So to implement this you'd probably want to factor out your logic that pulls data from .Input, assembles the stream fragment, and parses out and processes complete "messages" into a separate subroutine. This subroutine would be called both from the OnComm handler's comEvReceive condition and the Timer handler's .InBufferCount > 0 condition.

    The result is that you use MSComm's buffering and the OnComm event to reduce the amount of time you spend servicing received data. It should dramatically reduce the overhead of String concatenation by doing it much less frequently, and you could always improve it further by using a "fast string builder" Class.


    I don't know of any other clean and reliable way to handle data that arrives quickly via MSComm. We discussed this recently in Parsing continuous stream of comma delimited serial data from com port and the example I posted there using the technique described above seems to work at high arrival rates without data loss or UI responsiveness problems.

  16. #16
    PowerPoster
    Join Date
    Jul 2006
    Location
    Maldon, Essex. UK
    Posts
    6,334

    Re: Missing data from RS232

    Quote Originally Posted by dilettante View Post
    I don't see how using a polling loop is going to yield better performance than using OnComm properly. That approach is rife with warts and pitfalls.
    . etc........
    We don't have that either, but you can simulate it using a Timer control. In the Timer event handler you can test for .InBufferCount > 0 and if True then you'd grab and process the available data.
    This was what I was suggesting, perhaps you've expressed it more elequently than I managed to.

    Don't suppose we can do much more than wait for OP to come back with some more information regarding exactly what the constraints are.
    Last edited by Doogle; Jun 3rd, 2013 at 01:32 AM.

  17. #17

    Thread Starter
    Member
    Join Date
    May 2012
    Posts
    51

    Re: Missing data from RS232

    Thanks for the reply guys. Let me do some touch up on the programs. Will take note all your suggestion.

  18. #18
    PowerPoster
    Join Date
    Feb 2006
    Posts
    20,850

    Re: Missing data from RS232

    Quote Originally Posted by Doogle View Post
    This was what I was suggesting, perhaps you've expressed it more elequently than I managed to.
    More likely I just read your post too quickly and missed the point.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width