locked
SerialPort1.DataReceived does not fire?

    Question

  • I was perhaps too quick to think that VB's built-in event would be be easy to use.

    As you can see from my previous post I am building a program which sends and receives a few bytes from serial bus. The bus is actually a usb serial adapter, there are no real serial buses in my machine.

    Anyway that SerialPort1.DataReceived does not fire. It is from visual studio/vb ide so syntax should work?

    Here is my start up code. There are many comments, because I tried various combinations. These settings do not help.

          If Not _serialPort.IsOpen Then
                    If Not arvo = "" Then
                        _serialPort.DtrEnable = False
                        _serialPort.Parity = Parity.None
                        _serialPort.BaudRate = "9600"
                        _serialPort.PortName = arvo
                        _serialPort.Handshake = Handshake.None
                        ' SerialPort1.Handshake = IO.Ports.Handshake.None
                        _serialPort.RtsEnable = False
                        _serialPort.Encoding = System.Text.Encoding.Default
                        _serialPort.StopBits = StopBits.One
                        ' _serialPort.ReadTimeout = 1000
                        '   _serialPort.WriteTimeout = 500
                        _serialPort.Open()

    What is missing? Especially as there are no hand shaking with USB adapters I am using.
    Thursday, September 10, 2009 11:05 PM

Answers

  • Hi,

    it does look to me like you have placed one serialport component on your form, but use another one in your code. If you want to receive the events for your _serialPort then you should AddHandler to it.
    Your event like it is now just Handles SerialPort1.DataReceived.

    Add a Handler to it like:

    AddHandler _serialPort.DataReceived, AddressOf SerialPort1_DataReceived
    and remove the Handles SerialPort1.DataReceived from this method.

    and then you also need to call RemoveHandler before you are closing your application.


    If you have got questions about this, just ask.
    Mark the thread as answered if the answer helps you. This helps others who have the same problem !
    C# to VB.NET: http://www.developerfusion.com/tools/convert/csharp-to-vb/
    • Marked as answer by L M Sunday, September 13, 2009 4:29 PM
    Friday, September 11, 2009 10:04 AM
  • Heslacher is right, you have one port that you created in code, but the event handler is watching the events from a completely different object.

    It's like any other control--you don't put one on the form, and then instantiate a new one in your code and expect them to be the same object.
    You need to decide on whether you want a Serialport on your form at design time, and then attach to its events, or if you want to instantiate a serial port completely in code, and then add event handlers to it.

    The simplest way is the first one.  Don't declare a new serial port in your code, just change the settings and etc on the one on your form.

    I would create them in code in a case where I might have several at once, and they will change--say being added or removed from the computer--and I want to catch that and add/remove them in my program on the fly.  Otherwise, if the program will be used on a computer with a fixed COM port, I probably would add a fixed Serialport control to my form.
    • Marked as answer by L M Sunday, September 13, 2009 4:29 PM
    Friday, September 11, 2009 2:10 PM
  • It is very important when dealing with the serial port that you hold your mouth in just the right way while you wait to see whether or not it works properly.

    The problem that you are now having when the receive event fires is described here:

    http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/4ebccff7-baf6-4f2d-ae40-bb8733c2c805

    You cannot reference GUI components from the thread that the receive event is running on.  You can use a delegate for passing the information back to the GUI.
    • Marked as answer by L M Sunday, September 13, 2009 4:28 PM
    Saturday, September 12, 2009 2:32 AM
  • An example of a simple way to add a delegate to what you're doing:

    Imports System
    Imports System.IO
    Imports System.IO.Ports
    Imports System.Windows.Forms
    Imports System.Text
    
    Public Class Form1
    
        Shared merkit As Char
        Shared tulleet As Integer
        Shared polku, virheilm, merkki As String
        Private Delegate Sub dSetText(ByVal txt As String)
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            SerialPort1.WriteLine("r gfgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg")
        End Sub
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            SerialPort1.PortName = "COM4"
            SerialPort1.StopBits = StopBits.One
            SerialPort1.Handshake = Handshake.None
            ' SerialPort1.BaudRate = 9600
            SerialPort1.Open()
        End Sub
    
        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            SerialPort1.Close()
            Me.Close()
            Application.Exit()
        End Sub
    
        Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
            tulleet = SerialPort1.BytesToRead                       'break here does not "break"
            TextBox3_SetText(tulleet.ToString)
        End Sub
    
        Private Sub TextBox3_SetText(ByVal txt As String)
    
            If TextBox3.InvokeRequired Then
                Dim _dSetText As New dSetText(AddressOf TextBox3_SetText)
                Me.Invoke(_dSetText, New Object() {txt})
            Else
                TextBox3.Text = txt
            End If
    
        End Sub
    
    End Class

    • Marked as answer by L M Sunday, September 13, 2009 4:28 PM
    Saturday, September 12, 2009 5:10 PM

All replies

  • What is your code for the serial port receive event?  What is the value of arvo?  How have you confirmed that there is data being transmitted to the serial port?

    Have you  succeeded with serial communications with this device using a generic serial port communications utility?

    Depending on the device you are communicating with, you may find it easier to confirm that data transmit is working properly before attempting to receive.
    Friday, September 11, 2009 1:30 AM


  • The code shortened. I left off error handling and so on. There are controls from IDE toolbox, like serial port, buttons and so on:

    Imports System
    Imports System.IO
    Imports System.IO.Ports

    Imports System.Windows.Forms
    Imports System.Text

    Public Class Form1

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
                _serialPort.Write("r") 'send
            End If
        End Sub


        Shared merkit As Char
        Shared _serialPort As SerialPort

        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    'code to read used port from a file and check if the port is valid
            _serialPort = New SerialPort()
                        '   _serialPort.DtrEnable = False
                        _serialPort.Parity = Parity.None
                        _serialPort.BaudRate = "9600"
                        _serialPort.PortName = arvo
                        _serialPort.Handshake = Handshake.None
                        ' SerialPort1.Handshake = IO.Ports.Handshake.None
                        '   _serialPort.RtsEnable = False
                        ' _serialPort.Encoding = System.Text.Encoding.Default
                        _serialPort.StopBits = StopBits.One
                        ' _serialPort.ReadTimeout = 1000
                        '   _serialPort.WriteTimeout = 500
                        _serialPort.Open()

            Label6.Text = _serialPort.IsOpen
        End Sub


        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
             _serialPort.Close()
            Me.Close()
            Application.Exit()
       End Sub

     

        Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
            Dim montako As Integer
            TextBox2.Text = ""
            Try                                                   'breakpoints here
                If _serialPort.IsOpen Then              'and here, but they newer fire
                    If _serialPort.BytesToRead > 0 Then
                        merkit = ChrW(_serialPort.ReadChar())
                        If merkit = "V" Then
                            Label6.Text = "valmis"
                        End If
                        If merkit = "R" Then
                            Label6.Text = "Reset"
                        End If
                        TextBox2.Text = TextBox2.Text & merkit
                        montako = montako + 1
                    End If
                End If
            Catch ex As System.Exception
                virheilm = ex.Message
                _serialPort.DiscardInBuffer()
            End Try
            TextBox3.Text = montako
        End Sub
    End Class


    Arvo=com4  'it is the right port, see below

    Data is being sent to and from microcontroller, I have confirmed that with mc and with its development system. I am using VS2008 sp1. I have tried this with .Net 3.5 and .Net 2.0, the results are same. I'll start a new VB project from the beginning to test if there something I have done wrong.
    • Edited by L M Friday, September 11, 2009 9:36 AM cleaned the code a bit
    • Marked as answer by L M Sunday, September 13, 2009 4:29 PM
    • Unmarked as answer by L M Sunday, September 13, 2009 4:29 PM
    Friday, September 11, 2009 9:30 AM
  • Hi,

    it does look to me like you have placed one serialport component on your form, but use another one in your code. If you want to receive the events for your _serialPort then you should AddHandler to it.
    Your event like it is now just Handles SerialPort1.DataReceived.

    Add a Handler to it like:

    AddHandler _serialPort.DataReceived, AddressOf SerialPort1_DataReceived
    and remove the Handles SerialPort1.DataReceived from this method.

    and then you also need to call RemoveHandler before you are closing your application.


    If you have got questions about this, just ask.
    Mark the thread as answered if the answer helps you. This helps others who have the same problem !
    C# to VB.NET: http://www.developerfusion.com/tools/convert/csharp-to-vb/
    • Marked as answer by L M Sunday, September 13, 2009 4:29 PM
    Friday, September 11, 2009 10:04 AM
  • Heslacher is right, you have one port that you created in code, but the event handler is watching the events from a completely different object.

    It's like any other control--you don't put one on the form, and then instantiate a new one in your code and expect them to be the same object.
    You need to decide on whether you want a Serialport on your form at design time, and then attach to its events, or if you want to instantiate a serial port completely in code, and then add event handlers to it.

    The simplest way is the first one.  Don't declare a new serial port in your code, just change the settings and etc on the one on your form.

    I would create them in code in a case where I might have several at once, and they will change--say being added or removed from the computer--and I want to catch that and add/remove them in my program on the fly.  Otherwise, if the program will be used on a computer with a fixed COM port, I probably would add a fixed Serialport control to my form.
    • Marked as answer by L M Sunday, September 13, 2009 4:29 PM
    Friday, September 11, 2009 2:10 PM
  • Yes, I just realized that I took console program sample from a serial bus class and put that on a form application. Looks like it has been too long since I last did something with vb.

    This looks better now.
    Friday, September 11, 2009 3:02 PM
  • I removed extra declarations, but still no events. I can see that mcu is probably receiving something, but its response to the data is wrong and its reply is not received.

    Code now, all of it.

    Imports System
    Imports System.IO
    Imports System.IO.Ports

    Imports System.Windows.Forms
    Imports System.Text

    Public Class Form1

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            SerialPort1.WriteLine("r gfgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg")
        End Sub
     
        Shared merkit As Char
        Shared tulleet As Integer '
        Shared polku, virheilm, merkki As String

        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            SerialPort1.PortName = "COM4"
            SerialPort1.StopBits = StopBits.One
            SerialPort1.Handshake = Handshake.None
            ' SerialPort1.BaudRate = 9600
            SerialPort1.Open()
        End Sub

        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            SerialPort1.Close()
            Me.Close()
            Application.Exit()
        End Sub

        Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived  
            tulleet = SerialPort1.BytesToRead                       'break here does not "break"
            TextBox3.Text = tulleet
        End Sub

    End Class

    Friday, September 11, 2009 3:34 PM
  • Now suddenly I got SerialPort1.DataReceived events. I don't know why. I did not change anything.

    But now the compiler complains about SerialPort1.DataReceived  handler. It is a different thread, it says. Thought this kind of events are made to make it easy to update gui. I begin to understand extra code people are using. Delegates??

    So, what is the right way to handle incoming data from serial bus.
    Friday, September 11, 2009 10:26 PM
  • Hi
    I begin to understand the need for so much code and event handlers. SerialPort1.DataReceived event handler from ide is not a solution. A bug.

    Can you give a very short example of updating gui, when serial data arrives.

    Edit: Does Sharpdevelop have a working serial control?
    Friday, September 11, 2009 10:34 PM
  • It is very important when dealing with the serial port that you hold your mouth in just the right way while you wait to see whether or not it works properly.

    The problem that you are now having when the receive event fires is described here:

    http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/4ebccff7-baf6-4f2d-ae40-bb8733c2c805

    You cannot reference GUI components from the thread that the receive event is running on.  You can use a delegate for passing the information back to the GUI.
    • Marked as answer by L M Sunday, September 13, 2009 4:28 PM
    Saturday, September 12, 2009 2:32 AM
  • The link you gave looks interesting, I'll come back when I have tested the code. Thanks

    Are there more of these "factory built" events which are actually on a different thread. I grew up with VB6 and every event there where on the same thread, which made them very easy to use.
    Saturday, September 12, 2009 10:51 AM
  • The sample works, just. If I connect the mcu when Visual studio has started, everything works. I'll check the FTDI USB/serial chip, I heard it has time outs between normal mode and pio mode.
    Saturday, September 12, 2009 1:41 PM
  • An example of a simple way to add a delegate to what you're doing:

    Imports System
    Imports System.IO
    Imports System.IO.Ports
    Imports System.Windows.Forms
    Imports System.Text
    
    Public Class Form1
    
        Shared merkit As Char
        Shared tulleet As Integer
        Shared polku, virheilm, merkki As String
        Private Delegate Sub dSetText(ByVal txt As String)
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            SerialPort1.WriteLine("r gfgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg")
        End Sub
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            SerialPort1.PortName = "COM4"
            SerialPort1.StopBits = StopBits.One
            SerialPort1.Handshake = Handshake.None
            ' SerialPort1.BaudRate = 9600
            SerialPort1.Open()
        End Sub
    
        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            SerialPort1.Close()
            Me.Close()
            Application.Exit()
        End Sub
    
        Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
            tulleet = SerialPort1.BytesToRead                       'break here does not "break"
            TextBox3_SetText(tulleet.ToString)
        End Sub
    
        Private Sub TextBox3_SetText(ByVal txt As String)
    
            If TextBox3.InvokeRequired Then
                Dim _dSetText As New dSetText(AddressOf TextBox3_SetText)
                Me.Invoke(_dSetText, New Object() {txt})
            Else
                TextBox3.Text = txt
            End If
    
        End Sub
    
    End Class

    • Marked as answer by L M Sunday, September 13, 2009 4:28 PM
    Saturday, September 12, 2009 5:10 PM
  • Thank you and all the rest for the interesting codes. They helped, and I learned new things.

    The pc /MCU connection is working now (hopefully tomorrow also). The last problem was when Windows and Visual studio toggled DTR-pin and put the board into programming mode. That track is now cut.
    Sunday, September 13, 2009 4:28 PM