Microsoft Developer Network >
Forums Home
>
Visual Studio Express Editions Forums
>
Visual Basic Express Edition
>
Empty serial Port Read Buffer
Empty serial Port Read Buffer
- Is possible to empty read buffer of serial port component?
I'm become crazy to find a solution :-S
I am using this code
''''''''''''''''''''''''''''''''''
SerialPort1.PortName = portabacchetta.Text
SerialPort1.BaudRate = 9600
SerialPort1.Parity = IO.Ports.Parity.None
SerialPort1.DataBits = 8
SerialPort1.StopBits = IO.Ports.StopBits.One
SerialPort1.Handshake = IO.Ports.Handshake.None
SerialPort1.RtsEnable = True
SerialPort1.Open()
Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
Rx = SerialPort1.ReadExisting 'or SerialPort1.ReadLine SerialPort1.ReadExisting
SerialPort1.DiscardOutBuffer()
Me.Invoke(New EventHandler(AddressOf DoUpdate))
End Sub
Public Sub DoUpdate()
If Len(Rx) > 9 Then
TextBox2.Text = ""
TextBox2.Text = TextBox2.Text & Rx
TextBox1.Text = TextBox2.Text.Substring(0, TextBox2.Text.Length - 1)
If Rx = "000E41154A" Then
Label5.Text = "PROVA"
End If
End If
End Sub
Answers
- How have you declared RX? In VB, all strings are immutable, meaning you cannot change its length or contents once it is declared. Therefore, your code may only work once. Besides, you still expect RX to survive until DoUpdate() gets up and running. If more data are received, this may not be the case.
Try this instead:
Public Delegate Sub StringSubPointer(ByVal Buffer As String) ' Make a delegate to transfer the telegram
Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs) _
Handles SerialPort1.DataReceived
Me.BeginInvoke(New StringSubPointer(AddressOf DoUpdate), SerialPort1.ReadLine)
End Sub
Public Sub DoUpdate(ByVal Buffer As String)
TextBox2.Text = Buffer
.....
End Sub
Everything should be made as simple as possible, but not simpler. Any fool can write code that a computer can understand. Good programmers write code that humans understand.- Marked As Answer byMartin Xie - MSFTMSFT, ModeratorMonday, November 09, 2009 9:36 AM
All Replies
- What are you trying to do?
1) You use ReadExisting, but expect to receive an entire telegram (you test for Len(Rx) and compare with "000E41154A"). ReadExisting may return only one character. If you use ASCII and terminate your telegram with a fixed character like CR or LF, use ReadLine instead.
2) You discard the output buffer in the input routine. Why?
3) You ask how to empty the read buffer, but don't make any attempt to do so.
4) You don't transfer any content from your read routine to the display routine. You can do two things: You can read the telegram in the eventhandler for the DataReceived event, which is recommended if you use ReadLine, and then transfer the content to the UI thread in a delegate, or you can "wake" a subroutine on the UI thread and let this routine read from SerialPort. You have made a strange mix between these two methods. Since the DataReceived event may fire at any time, you cannot expect the buffer RX to survive as you do.
I have written a very big SerialPort tutorial, which may be helpful to you: http://www.innovatic.dk/knowledg/SerialCOM/SerialCOM.htm
Everything should be made as simple as possible, but not simpler. Any fool can write code that a computer can understand. Good programmers write code that humans understand. - Thank's a lot for you interest to my question!! :-)
Let's explain my problem.
I have an rfid read that comunicate with computer on com port. I have to read an rfid tag by antenna and compare this tag code with a string, but when i put the tag near RFID ANTENNA, i have thist situation:
1) Firs time i have value: 0E28E1D7L
2) SECOND TIME E28E1D7
3) THIRTH TIME 0000E28E1D7
4) FORUTH TIME 000E28E1D7
5) FIFTH TIME E28E1D7
is this probably an buffer problem?
thank's a lot and excuse for my english - No, I don't think that it is a buffer problem. It is probably due to the way you receive.
The most important thing og ANY communication is to have a communication protocol, which makes it possible to recognize either the beginning or the end of a telegram. If you don't have such a protocol, the slightest error may bring you totally out of synchronization (as in your case).
First, find out if the telegrams from your RFID reader is terminated with a given ASCII character. If they are, use ReadLine and set the NewLine character to this character. Then you can marshal the received telegram to the UI thread as described in my tutorial.
Everything should be made as simple as possible, but not simpler. Any fool can write code that a computer can understand. Good programmers write code that humans understand. - This all looks correct to me. You must parse the results of the reads, and not assume anything about the content until you have a full read (and discard any data that doesn't contribute). What is the value of the little "box symbol?" This is the delimiter that you will use to determine a full read -- that is, everything between two "box symbols" is one read. I might presume that this is a vbCr character (Chr(13)), but only you can tell for sure, either by documentation, or simply observing the value as you step through the code. Parsing will be straight forward, as soon as you know the value.
Dick
Dick Grier, MVP. Author of Visual Basic Programmer's Guide to Serial Communications 4. See www.hardandsoftware.net. - Ok, thank's a lot, i have solved with this solution, obtaining 12 char value, ad it is good for me :-D...thank's a lot.
DoUpdate() If Len(Rx) > 9 Then codicetag = Rx.Remove(0, 2) TextBox2.Text = codicetag
But now i have another problem, because i have to compare runtime the value i receive from serial port with a textBox valute ..ie it seems do not compare nothig :-( or probably it not work in runtime?..
WITH OLD VB6 I DOES IT SO:
Private Sub MSComm1_OnComm() Dim Rx$ Rx$ = MSComm1.Input
If Len(Rx$) > 9 Then
Text2.Text = "" Text2.Text = Text2.Text & Rx$ If Rx$ = "04158229FA" Then
Text3.Text = "ciao"
ElseIf Rx$ = "0F02D759C4" Then
Text3.Text = "PIZZA"
WHI IT DO NOT WORK IN VB.NET?
Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived Rx = SerialPort1.ReadLine() Me.Invoke(New EventHandler(AddressOf DoUpdate)) End Sub Public Sub DoUpdate() If Len(Rx) > 9 Then codicetag = Rx.Remove(0, 2) TextBox2.Text = codicetag End If
If TextBox2.Text = TextBox3.Text Then Label5.Text = "DOG" ElseIf TextBox2.Text = TextBox4.Text Then Label5.Text = "HOUSE" ElseIf TextBox2.Text = TextBox5.Text Then Label5.Text = "CAT" ElseIf TextBox2.Text = TextBox6.Text Then Label5.Text = "GARDEN" ElseIf TextBox2.Text = TextBox7.Text Then Label5.Text = "CAR" ElseIf TextBox2.Text = TextBox8.Text Then Label5.Text = "--GAME OVER ---" End If end sub - How have you declared RX? In VB, all strings are immutable, meaning you cannot change its length or contents once it is declared. Therefore, your code may only work once. Besides, you still expect RX to survive until DoUpdate() gets up and running. If more data are received, this may not be the case.
Try this instead:
Public Delegate Sub StringSubPointer(ByVal Buffer As String) ' Make a delegate to transfer the telegram
Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs) _
Handles SerialPort1.DataReceived
Me.BeginInvoke(New StringSubPointer(AddressOf DoUpdate), SerialPort1.ReadLine)
End Sub
Public Sub DoUpdate(ByVal Buffer As String)
TextBox2.Text = Buffer
.....
End Sub
Everything should be made as simple as possible, but not simpler. Any fool can write code that a computer can understand. Good programmers write code that humans understand.- Marked As Answer byMartin Xie - MSFTMSFT, ModeratorMonday, November 09, 2009 9:36 AM

