|
-
Apr 15th, 2010, 08:32 AM
#1
Thread Starter
Lively Member
serialport
Hi,
I need to create a program that sends & receives data via rs232.
I have done it many times in VB6 with easy.
Why is so hard in vs2008?
I managed to send (or so I think).
Because I can see the LEDs flashing on my board connected to the pc.
But I do not get any response back from the board.
The reason I do it in vs2008, is because I need the program to run on a PDA.
But to understand how rs232 works in vs2008, I just created a simple program for the pc to talk to my board.
for example, I send:
Code:
SerialPort1.Write(Chr(2) & "I" & Chr(3))
and I expect back (into a textbox), a hex string 25 characters long.
The board also send data to rs232 sometimes, without me requesting it.
How do I do it?
Thanks.
-
Apr 15th, 2010, 09:11 AM
#2
Re: serialport
 Originally Posted by HyperUniverse
Why is so hard in vs2008?
They made it hard on purpose just to annoy VB6 developers. Then again, maybe it's just that you're not familiar with it that makes it hard.
-
Apr 15th, 2010, 10:46 AM
#3
Fanatic Member
Re: serialport
What code are you using?
To read data, you would assign receive data to a buffer array of type Byte, and use the Read method. Example,
Dim Buffer(SerialPort1.BytesToRead -1) As Byte
SerialPort1.Read(Buffer, 0, SerialPort1.BytesToRead)
Now, to use the DataReceived event, which executes in the background thread context of the SerialPort object, you have to marshall the data from the event using a Delegate. The UI is STAThread, so you have to add some extra code to display information from DataReceived events to avoid a cross-thread exception.
I have example code that shows this process on my homepage, www.hardandsoftware.net. Go to Software Downloads and select Visual Studio Serial Terminal Example download.
Dick
Richard Grier, Consultant, Hard & Software
Microsoft MVP (Visual Basic)
-
Apr 16th, 2010, 03:25 AM
#4
Thread Starter
Lively Member
Re: serialport
DickGrier
Thanks for trying to help me.
Unfortunately your example is written for vs2005, and when I import it in vs2008 I get loads of errors.
In the end the program does nothing.
Anyway that is a big-BIG piece of coding for my needs.
This is the vb6 example, that I want to "convert" into vs2008:
Code:
Private Sub cmdVersion_Click() 'version no
On Error Resume Next
MSComm1.Output = Chr$(2) & "I" & Chr$(3)
End Sub
Private Sub MSComm1_OnComm()
Dim InBuff As String
Select Case MSComm1.CommEvent
' Handle each event or error by placing
' code below each case statement.
' This template is found in the Example
' section of the OnComm event Help topic
' in VB Help.
' Errors
Case comEventBreak ' A Break was received.
Case comEventCDTO ' CD (RLSD) Timeout.
Case comEventCTSTO ' CTS Timeout.
Case comEventDSRTO ' DSR Timeout.
Case comEventFrame ' Framing Error.
Case comEventOverrun ' Data Lost.
Case comEventRxOver ' Receive buffer overflow.
Case comEventRxParity ' Parity Error.
Case comEventTxFull ' Transmit buffer full.
Case comEventDCB ' Unexpected error retrieving DCB]
' Events
Case comEvCD ' Change in the CD line.
Case comEvCTS ' Change in the CTS line.
Case comEvDSR ' Change in the DSR line.
Case comEvRing ' Change in the Ring Indicator.
Case comEvReceive ' Received RThreshold # of chars.
InBuff = MSComm1.Input
Call HandleInput(InBuff)
Case comEvSend ' There are SThreshold number of
' characters in the transmit buffer.
Case comEvEOF ' An EOF character was found in the
' input stream.
End Select
End Sub
Sub HandleInput(InBuff As String)
txtIncome.SelStart = Len(txtIncome.Text)
txtIncome.SelText = InBuff
End Sub
As you see this is very simple, nothing complicated, and it works perfect.
Now, in vs2008 I did this:
Code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
SerialPort1.Write(Chr(2) & "I" & Chr(3))
End Sub
Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As _
System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
TextBox1.SelectedText = SerialPort1.ReadLine
End Sub
Shouldn't this work?
Oh, and another thing:
In vb6 I have Handshake set to comRTS.
But if I set handshake to Request to Send in vs2008 the program seems to freeze after I press the button.
Thanks.
-
Apr 16th, 2010, 11:07 AM
#5
Fanatic Member
Re: serialport
I've imported the code dozens of times, with no errors. If you send me email, I'll ZIP a copy of it to in response. My contact information is on my site.
Did you look at my code (DataReceived event code)? This should answer your questions. That is, how to read data, and then call a Delegate to put that data in a textbox.
ReadLine blocks, waiting for a vbCrLf in the receive data, then makes data availalble. However, as I said before, you cannot make direct changes to the UI (textbox, for example) from the DataReceived event. You must use call a Delegate which executes in the STAThread context of the UI, not the background context of the SerialPort DataReceived event.
You code should generate a cross-threading exception, but... I've seen times when there was no error generated, and the code simply appears to lock up.
Dick
Richard Grier, Consultant, Hard & Software
Microsoft MVP (Visual Basic)
-
Apr 16th, 2010, 05:55 PM
#6
Thread Starter
Lively Member
Re: serialport
I have found a 95% solution.
This is the code now, that almost works perfect;
Code:
Public Class Form1
'My serial port with events already hooked in. The wonders of Visual Basic's rocking event handling. :)
Private WithEvents serial As New IO.Ports.SerialPort
'This is my Delegate. It's the box that'll carry the String data from the receival thread to the main one.
Private Delegate Sub UpdateTextboxDelegate(ByVal myText As String)
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'When the main application thread finished building the form, it runs this and configures and opens our serial port.
serial.BaudRate = 9600
serial.PortName = "COM7"
serial.Open()
End Sub
Private Sub btSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btSend.Click
serial.Write(Chr(2) & "I" & Chr(3))
End Sub
Private Sub serial_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles serial.DataReceived
'When this event happens, it's being processed by a second thread; one that's automatically created by the serialport
'object.
On Error Resume Next
' Dim myResponse As String = serial.ReadLine
Dim myResponse As String = serial.ReadExisting
UpdateTextbox(myResponse)
End Sub
Private Sub UpdateTextbox(ByVal myText As String)
'First, check if the control we're updating requires an invoke.
'This is just a simple test of the thread that's calling the function vs. the thread that created the control.
If Me.txtIncomming.InvokeRequired Then
'This means the thread that's calling this function is NOT the one that created the TextBox.
'So, it makes a new delegate and tells it to send the data right back to this same function.
Dim d As New UpdateTextboxDelegate(AddressOf UpdateTextbox)
'This tells the main application thread that it's waiting for it to process. The data received thread is now complete.
Me.txtIncomming.Invoke(d, New Object() {myText})
Else
'When the main application threas picks up the delegate, it'll run "UpdateTextbox" with the data it was handed.
'So, it'll pass the InvokeRequired test since the main application thread IS the thread that made the Textbox as well,
'thus, it'll just set the value as you'd expect it to.
' txtIncomming.Text = myText
txtIncomming.SelectedText = txtIncomming.selectedText & myText
End If
End Sub
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
'Don't forget to close your port when shutting down!
If serial.IsOpen Then serial.Close()
End Sub
Private Sub btClear_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btClear.Click
txtIncomming.Text = ""
End Sub
End Class
On the testing program (on the pc), there is just one textbox and 2x buttons.
The way the code above is now, when I press the button btSend, the board responds as it should with a data string, but the next string (after this), comes on the same line in the textbox.
I would like it on a new line in the textbox.
If I keep pressing btSend, then every next string comes on the same line, appending to the old data string.
When the board sends data "un-requested" I get every string on a new line.
This works perfect.
I believe is has to do with CR.
When I request a transmission, "data" is sent and received inside Chr(2)..data..Chr(3).
But when the board transmits data "un-requested", this data begins with 55...data...and ends with a carriage return (I think so).
Ideal would be to receive requested data in a textbox, each string on a new line.
And the un-requested data into a different textbox, each string on a new line.
Another minor problem is the font.
In VB6 I was using Terminal.
In VS2008 seems this is missing.
I thought the fonts are from within the operating system (winXP Pro).
I like Terminal as it has nice shapes for chr(2) & chr(3).
Any ideea how to get it back?
Regards.
-
Apr 17th, 2010, 09:02 PM
#7
Fanatic Member
Re: serialport
Append each string with vbCrLf (or ControlChars.NewLine, which is the same thing).
Dick
Richard Grier, Consultant, Hard & Software
Microsoft MVP (Visual Basic)
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|