Solved

serial port vb.net 2005 loop problem

Posted on 2006-10-24
7
7,915 Views
Last Modified: 2011-08-18
Hello,

I downloaded this code from the web (devx) as a way to get some practice with serial ports in vb.net 2005.  I am trying to communicate with a serial port device that has a database of records.  In this example, it has 147.  The device requires a login so I type it in and hit the send button and now it should loop through and display all of the records in the device via the updateTextBox sub.  However, it does not but when I debug and walk through it to see what problem is, it works fine.  All the records appear to be displayed properly.  Also, when I do use the default code that requires hitting send button with command to serial device it works everytime for 1 record but I am unable to get the code to work with looping through records.  Is this a timing issue ?


Imports Microsoft.VisualBasic

Public Class Form1
    Dim WithEvents serialPort As New IO.Ports.SerialPort

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

        For i As Integer = 0 To _
           My.Computer.Ports.SerialPortNames.Count - 1
            cbbCOMPorts.Items.Add( _
               My.Computer.Ports.SerialPortNames(i))
        Next
        btnDisconnect.Enabled = False
    End Sub

    Private Sub DataReceived( _
       ByVal sender As Object, _
       ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) _
       Handles serialPort.DataReceived

        txtDataReceived.Invoke(New _
                       myDelegate(AddressOf updateTextBox), _
                       New Object() {})
    End Sub

    Private Sub btnSend_Click( _
       ByVal sender As System.Object, _
       ByVal e As System.EventArgs) _
       Handles btnSend.Click
        'temp code



        Try
            serialPort.Write(Chr(2) & txtDataToSend.Text & Chr(13))
            With txtDataReceived
                .SelectionColor = Color.Black
                .AppendText(txtDataToSend.Text & Chr(13))
                .ScrollToCaret()
            End With
            txtDataToSend.Text = String.Empty

        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try


      ' Here is my added code to have it loop through to get all the records
        Dim Number As Integer = 0
        Dim Number2Hex As String = ""


        Do While Number < 147

            Number2Hex = Conversion.Hex(Number)
            Try
                'serialPort.Write(Chr(2) & txtDataToSend.Text & Chr(13))
                If Number2Hex.Length = 1 Then
                    serialPort.Write(Chr(2) & "G400" & Number2Hex & Chr(13))

                ElseIf Number2Hex.Length = 2 Then
                    serialPort.Write(Chr(2) & "G40" & Number2Hex & Chr(13))

                ElseIf Number2Hex.Length = 3 Then
                    serialPort.Write(Chr(2) & "G4" & Number2Hex & Chr(13))

                End If

                With txtDataReceived
                    .SelectionColor = Color.Black
                    .AppendText(txtDataToSend.Text & Chr(13))
                    .ScrollToCaret()
                End With
               'do not need line below as Im having it loop through
               ' txtDataToSend.Text = String.Empty

            Catch ex As Exception
                MsgBox(ex.ToString)
            End Try

            Number = Number + 1

        Loop

        'End If

    End Sub

    Public Delegate Sub myDelegate()
    Public Sub updateTextBox()
        With txtDataReceived
            .Font = New Font("Garamond", 12.0!, FontStyle.Bold)
            .SelectionColor = Color.Red
            .AppendText(serialPort.ReadExisting)
            .ScrollToCaret()
        End With
    End Sub

    Private Sub btnConnect_Click( _
      ByVal sender As System.Object, _
      ByVal e As System.EventArgs) _
      Handles btnConnect.Click
        If serialPort.IsOpen Then
            serialPort.Close()
        End If
        Try
            With serialPort
                .PortName = cbbCOMPorts.Text
                .BaudRate = 9600
                .Parity = IO.Ports.Parity.None
                .DataBits = 8
                .StopBits = IO.Ports.StopBits.One
            End With
            serialPort.Open()
            lblMessage.Text = cbbCOMPorts.Text & " connected."
            btnConnect.Enabled = False
            btnDisconnect.Enabled = True
        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try
    End Sub

    Private Sub btnDisconnect_Click( _
       ByVal sender As System.Object, _
       ByVal e As System.EventArgs) _
       Handles btnDisconnect.Click
        Try
            serialPort.Close()
            lblMessage.Text = serialPort.PortName & " disconnected."
            btnConnect.Enabled = True
            btnDisconnect.Enabled = False
        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try
    End Sub
End Class
0
Comment
Question by:hawkeen
  • 3
  • 3
7 Comments
 
LVL 24

Accepted Solution

by:
Jeff Certain earned 500 total points
ID: 17814636
Sounds like a timing issue to me. You're probably looping faster than the device can process, expecially at 9600 baud.

I've added a delay loop for you to slow things down. Probably slower than it needs to be, but that's okay (at least for testing). I've made some other changes to clean up your code. These are mostly changes that will make your life easier as a developer; you may want to look them over. In particular, I changed your delegate call to check to see if an invoke is required; you can now use this anywhere you need to update the text box. (One note -- invokes are only required in a multi-threaded application; I didn't see anywhere taht you were explicitly multi-threading; the invoke may not be requried at all).

Public Class Form1
  Private WithEvents serialPort As New IO.Ports.SerialPort

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

    For Each portName As String In My.Computer.Ports.SerialPortNames
      cbbCOMPorts.Items.Add(portName)
    Next

    btnDisconnect.Enabled = False
  End Sub

  Private Sub DataReceived( _
     ByVal sender As Object, _
     ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) _
     Handles serialPort.DataReceived

    updateTextBox(serialPort.ReadExisting)
  End Sub

  Private Sub btnSend_Click( _
     ByVal sender As System.Object, _
     ByVal e As System.EventArgs) _
     Handles btnSend.Click

    Try
      serialPort.Write(Chr(2) & txtDataToSend.Text & Chr(13))
      updateTextBox(txtDataToSend.Text & Chr(13))
      txtDataToSend.Text = String.Empty
    Catch ex As Exception
      MsgBox(ex.ToString)
    End Try

    ' Here is my added code to have it loop through to get all the records
    For number As Integer = 0 To 146
      Dim Number2Hex As String = Conversion.Hex(number)
      Try
        Select Case Number2Hex.Length
          Case 1
            serialPort.Write(Chr(2) & "G400" & Number2Hex & Chr(13))
          Case 2
            serialPort.Write(Chr(2) & "G40" & Number2Hex & Chr(13))
          Case 3
            serialPort.Write(Chr(2) & "G4" & Number2Hex & Chr(13))
        End Select

        updateTextBox(txtDataToSend.Text & Chr(13))
      Catch ex As Exception
        MsgBox(ex.ToString)
      End Try

      ' Put the current thread to sleep for 1 second
      System.Threading.Thread.CurrentThread.Sleep(1000)
    Next number
  End Sub

  Public Delegate Sub updateTextboxDelegate(ByVal text As String)
  Public Sub updateTextBox(ByVal text As String)
    If txtDataReceived.InvokeRequired Then
      txtDataReceived.Invoke(New updateTextboxDelegate(AddressOf updateTextBox), New Object() {text})
    Else
      With txtDataReceived
        .Font = New Font("Garamond", 12.0!, FontStyle.Bold)
        .AppendText(text)
        .ScrollToCaret()
      End With
    End If
  End Sub

  Private Sub btnConnect_Click( _
    ByVal sender As System.Object, _
    ByVal e As System.EventArgs) _
    Handles btnConnect.Click
    If serialPort.IsOpen Then
      serialPort.Close()
    End If
    Try
      With serialPort
        .PortName = cbbCOMPorts.Text
        .BaudRate = 9600
        .Parity = IO.Ports.Parity.None
        .DataBits = 8
        .StopBits = IO.Ports.StopBits.One
      End With
      serialPort.Open()
      lblMessage.Text = cbbCOMPorts.Text & " connected."
      btnConnect.Enabled = False
      btnDisconnect.Enabled = True
    Catch ex As Exception
      MsgBox(ex.ToString)
    End Try
  End Sub

  Private Sub btnDisconnect_Click( _
     ByVal sender As System.Object, _
     ByVal e As System.EventArgs) _
     Handles btnDisconnect.Click
    Try
      serialPort.Close()
      lblMessage.Text = serialPort.PortName & " disconnected."
      btnConnect.Enabled = True
      btnDisconnect.Enabled = False
    Catch ex As Exception
      MsgBox(ex.ToString)
    End Try
  End Sub
End Class
0
 

Author Comment

by:hawkeen
ID: 17814687
Just a quick note before I test this out.  Microsoft states that the serial port dataReceived event is not handled on the same GUI thread but is instead handled on another separate process thread and that is why the invoke is needed.  Did you compile this and test it by any chance?

cheers
Hawk
0
 
LVL 24

Expert Comment

by:Jeff Certain
ID: 17814743
Well, I have no device, so I didn't test it.

However, I've used that invoke approach in the past to do my threading talk for local user groups. It should be good. :)

The only thing I saw was one warning about the sleep call (it's a shared method call, but it thinks I'm calling it against a specific thread... it works, too)
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:hawkeen
ID: 17975990
It was a timing issue but you have to use delegates to make it work.  Chaosian should get the points because he did provide some help.

cheers
Hawk
0
 
LVL 24

Expert Comment

by:Jeff Certain
ID: 17978881
By delegates, do you mean that you have to call Invoke? If so, that was in my solution.

If not, can you post the solution so that people who search the archives can find it, please?
0
 

Author Comment

by:hawkeen
ID: 18010112
The invoke is required because Microsoft states that DataReceived event will handle serial port data from a separate non gui worker thread.  In order to update a main form control you have to use the invoke method.

Not having the hardware device there makes it hard to see all of this and I do appreciate your help chaosian.

Now I am going to post another question relating to looping through available com ports.  Thanks.

cheers
Hawk
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

Well, all of us have seen the multiple EXCEL.EXE's in task manager that won't die even if you call the .close, .dispose methods. Try this method to kill any excels in memory. You can copy the kill function to create a check function and replace the …
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

707 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

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now