Link to home
Start Free TrialLog in
Avatar of imarshad
imarshadFlag for Pakistan

asked on

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
Avatar of imarshad
imarshad
Flag of Pakistan image

ASKER

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
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
Avatar of arif_eqbal
arif_eqbal

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 ????

ASKER CERTIFIED SOLUTION
Avatar of Bob Learned
Bob Learned
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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
>>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
That was untested code, since I don't have any serial device:

testString.IndexOf

Bob
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
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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
Maybe you can also help me in the other question that I have asked at

https://www.experts-exchange.com/questions/21375061/Bitmap-related.html

Imran
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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