Reading serial port.....

Hi all,
        I am developing for a windows CE.NET device.... I am using Serial IO class in Smart Device Framework found on the following page
http://www.opennetcf.org/CategoryView.aspx?category=Home

to develop an application that will read data from GPS on a Serial Port..... The class exposes an event SerialPort_DataReceived() which is fired each time a new character is received at the Comm Port(Similar to OnComm in VB6)..... Using the following code I am able to display whatever comes on the serial port in a Textbox.......

    Private Sub SerialPort_DataReceived() Handles SerialPort.DataReceived
        Dim Buffer(SerialPort.InBufferCount - 1) As Byte
        Buffer = SerialPort.Input
       
       TextBox1.Text = TextBox1.Text & (Encoding.ASCII.GetString(Buffer, 0, Buffer.Length))

    End Sub



For those who donot know about GPS the following are the six GPS strings that the receiver sends every second to the Serial port which we can read...

$GPGGA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,M,<11>,<12>,<13><CR><LF>
$GPGLL,<1>,<2>,<3>,<4>,<5>,<6>,<7><CR><LF>
$GPGSA,<1>,<2>,<3>,<3>,,,,,<3>,<3>,<3>,<4>,<5>,<6>,<7><CR><LF>
$GPGSV,<1>,<2>,<3>,<4>,<5>,<6>,<7>,…<4>,<5>,<6>,<7>,<8><CR><LF>
$GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11><CR><LF>
$GPVTG,<1>,T,<2>,M,<3>,N,<4>,K,<5><CR><LF>

Out of these 6 strings only 2 are of my interest and they are GPGGA and GPRMC..... So I want some intelligence in the  SerialPort_DataReceived() event so that whenever I have received both GPGGA and GPRMC an event is fired that will tell me that both the strings are ready to be used......

I hope my question is clear now.....

Imran
LVL 13
imarshadAsked:
Who is Participating?
 
Bob LearnedCommented:
Something like this maybe:

Public Event ValidData(ByVal input As String)

Private _buildInput As New System.Text.StringBuilder()

Private Sub SerialPort_DataReceived() Handles SerialPort.DataReceived

     Dim Buffer(SerialPort.InBufferCount - 1) As Byte
     Buffer = SerialPort.Input
       
     _buildInput.Append(Encoding.ASCII.GetString(Buffer, 0, Buffer.Length))

     Dim testString As String = _buildInput.ToString

     If testString.IndexOf("GPGGA") > -1 And testString.Index("GPRMC") > -1 Then
        RaiseEvent ValidData(testString)
     End If

End Sub

Bob
0
 
imarshadAuthor Commented:
I know how to parse and use the data once it is stored in some string variable.... All I want to know is some method that will tell me that the data is ready to be used....

Imran
0
 
imarshadAuthor Commented:
This is the VB6 version that I got here on EE..... It is working very well in VB6 and eVB but I have not been able to port it to VB.NET

Private sBuffer as string
Private sString as string
Private Sub MSComm1_OnComm()
    Select Case MSComm1.CommEvent
        Case comEvReceive   ' Received RThreshold # of chars.        
            sBuffer = sBuffer & MSComm1.Input
            Do Until Len(sBuffer) = 0
                 Call ProcessCom(Left(sBuffer, 1))
                 sBuffer = Mid(sBuffer, 2)
            Loop
    End Select
End Sub

Private Sub ProcessCom(cChar As String)
    If cChar <> vbCr And cChar <> vbLf Then
        sString = sString + cChar
    End If
    If cChar = vbLf Then 'End Of Line
        If InStr(sString, "GPGGA") > 0 Then 'Valid Line
           msgbox "Do what needs to be done here."
           sString = ""
    End If
End Sub

Imran
0
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

 
arif_eqbalCommented:
So you are able to Display the data in TextBox is it???

 Private Sub SerialPort_DataReceived() Handles SerialPort.DataReceived
        Dim Buffer(SerialPort.InBufferCount - 1) As Byte
        Buffer = SerialPort.Input
       TextBox1.Text = TextBox1.Text & (Encoding.ASCII.GetString(Buffer, 0, Buffer.Length))

    End Sub

What does it display?? The first line you posted from the GPS data ????

0
 
arif_eqbalCommented:
Hi TheLearnedOne
That's the way of course but it depends how the data is streaming
I mean if all the Lines are recieved in one go then your code will work fine
If the lines come one by one say after a small delay then he will need to Test for
GPGGA and GPRMC separately

That's why I asked what does his code show in text Box

Anyway in case its one line at a time you can just change the AND to OR

If testString.IndexOf("GPGGA") > -1 OR testString.Index("GPRMC") > -1 Then
        RaiseEvent ValidData(testString)
End If
0
 
imarshadAuthor Commented:
>>What does it display?? The first line you posted from the GPS data ????
No it displays all the data coming from the GPS....

I hav tried the code that you have suggested.... It is almost working fine.... Only a couple of problems....

1) testString.Index("GPRMC") > -1 is generating compile error that Index is not a member of String... I have replaced it with IndexOf..... Have I done it right????

2)If testString.IndexOf("GPGGA") > -1 And testString.IndexOf("GPRMC") > -1 Then

This condition is even true when the whole GPRMC string has not reached..... What I need to make sure is that even after testString.IndexOf("GPRMC") > -1 I should also check for a "Carriage Return" "Line Feed" after GPRMC is received. This check will allow me to have the full GPRMC string read before the event is fired.....

Imran
0
 
Bob LearnedCommented:
That was untested code, since I don't have any serial device:

testString.IndexOf

Bob
0
 
imarshadAuthor Commented:
This is the logic I am using......(It is successfull)
   
     If testString.IndexOf("GPRMC") > -1 Then  
            If testString.LastIndexOf(vbCr) > testString.LastIndexOf("GPRMC") Then
                Call ValidData(testString)
                'Me.Invoke(New EventHandler(AddressOf ValidData(testString)))
                _buildInput.Remove(0, _buildInput.Length)
            End If
     End If

Please suggest me if it can be done more efficiently??? The reason I am more concerned about it, is that it will run all the time my program is running.... and I want to make sure that it is the most efficient and there is no memry leak in it..... I am looking forward for your reply and better suggestions.....

Imran Arshad
0
 
Bob LearnedCommented:
One improvement:

If testString.IndexOf("GPRMC") > -1 AndAlso testString.LastIndexOf(vbCr) > testString.LastIndexOf("GPRMC") Then
    ValidData(testString)
    _buildInput = New StringBuilder()
End If

If the amount of data received is fixed, then you can also instantiate a StringBuilder with a known size.

_buildInput = New StringBuilder(1000)

Bob
0
 
imarshadAuthor Commented:
Please suggest that raising an event will be more efficient or calling a function

RaiseEvent ValidData(testString)

or

call ValidData(testString)

and also you have suggested to use
_buildInput = New StringBuilder()

instead of

_buildInput.Remove(0, _buildInput.Length)

So will VB.NET do the memory management for me??? I mean I will be each time decalaring an object of the class StringBuilder.....
Please forgive me for the silly questions I am asking as I am very new to VB.NET.... Only 1 week since I have been working on VB.NET......

Imran
0
 
imarshadAuthor Commented:
Maybe you can also help me in the other question that I have asked at

http://www.experts-exchange.com/Programming/Programming_Languages/Dot_Net/VB_DOT_NET/Q_21375061.html

Imran
0
 
Bob LearnedCommented:
Yes, VB.NET will automatically do the memory management for you.

The RaiseEvent is only necessary if you want to indicate to some other class that valid data has been received.  If the processing is kept inside of the same class, then a method call would be sufficient.

Bob
0
 
imarshadAuthor Commented:
One last question:
                           Imagine a case when the function call ValidData(testString) takes more then 1 second to complete..... But the data stream continuously arrives and I will receive GPRMC in one second..... Now I am still in the ValidData function(Doing some manipulations there) and I will be calling it again...... What will  happpen? Will the function be called again even if I havenot exited from the earlier function call?

Imran
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.