Results 1 to 7 of 7

Thread: serialport

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Mar 2010
    Posts
    78

    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.

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: serialport

    Quote Originally Posted by HyperUniverse View Post
    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.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  3. #3
    Fanatic Member
    Join Date
    Sep 2009
    Location
    Lakewood, Colorado
    Posts
    621

    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)

  4. #4

    Thread Starter
    Lively Member
    Join Date
    Mar 2010
    Posts
    78

    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.

  5. #5
    Fanatic Member
    Join Date
    Sep 2009
    Location
    Lakewood, Colorado
    Posts
    621

    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)

  6. #6

    Thread Starter
    Lively Member
    Join Date
    Mar 2010
    Posts
    78

    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.

  7. #7
    Fanatic Member
    Join Date
    Sep 2009
    Location
    Lakewood, Colorado
    Posts
    621

    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
  •  



Click Here to Expand Forum to Full Width