?
Solved

Reading serial port.....

Posted on 2005-04-07
13
Medium Priority
?
1,471 Views
Last Modified: 2009-03-02
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
0
Comment
Question by:imarshad
  • 7
  • 4
  • 2
13 Comments
 
LVL 13

Author Comment

by:imarshad
ID: 13725611
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
 
LVL 13

Author Comment

by:imarshad
ID: 13725633
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
 
LVL 19

Expert Comment

by:arif_eqbal
ID: 13725715
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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 96

Accepted Solution

by:
Bob Learned earned 2000 total points
ID: 13726014
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
 
LVL 19

Expert Comment

by:arif_eqbal
ID: 13726114
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
 
LVL 13

Author Comment

by:imarshad
ID: 13734588
>>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
 
LVL 96

Expert Comment

by:Bob Learned
ID: 13735373
That was untested code, since I don't have any serial device:

testString.IndexOf

Bob
0
 
LVL 13

Author Comment

by:imarshad
ID: 13738065
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
 
LVL 96

Assisted Solution

by:Bob Learned
Bob Learned earned 2000 total points
ID: 13738130
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
 
LVL 13

Author Comment

by:imarshad
ID: 13740047
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
 
LVL 13

Author Comment

by:imarshad
ID: 13740101
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
 
LVL 96

Assisted Solution

by:Bob Learned
Bob Learned earned 2000 total points
ID: 13740106
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
 
LVL 13

Author Comment

by:imarshad
ID: 13743234
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

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This tutorial demonstrates one way to create an application that runs without any Forms but still has a GUI presence via an Icon in the System Tray. The magic lies in Inheriting from the ApplicationContext Class and passing that to Application.Ru…
Introduction When many people think of the WebBrowser (http://msdn.microsoft.com/en-us/library/2te2y1x6%28v=VS.85%29.aspx) control, they immediately think of a control which allows the viewing and navigation of web pages. While this is true, it's a…
this video summaries big data hadoop online training demo (http://onlineitguru.com/big-data-hadoop-online-training-placement.html) , and covers basics in big data hadoop .
In a question here at Experts Exchange (https://www.experts-exchange.com/questions/29062564/Adobe-acrobat-reader-DC.html), a member asked how to create a signature in Adobe Acrobat Reader DC (the free Reader product, not the paid, full Acrobat produ…

862 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question