Solved

serial port vb.net 2005 loop problem

Posted on 2006-10-24
7
7,927 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
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 

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

Active Directory Webinar

We all know we need to protect and secure our privileges, but where to start? Join Experts Exchange and ManageEngine on Tuesday, April 11, 2017 10:00 AM PDT to learn how to track and secure privileged users in Active Directory.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to create and use a custom WaterMark textbox class.  The custom WaterMark textbox class allows you to set the WaterMark Background Color and WaterMark text at design time.   IMAGE OF WATERMARKS STEPS Create VB …
It’s quite interesting for me as I worked with Excel using vb.net for some time. Here are some topics which I know want to share with others whom this might help. First of all if you are working with Excel then you need to Download the Following …
Nobody understands Phishing better than an anti-spam company. That’s why we are providing Phishing Awareness Training to our customers. According to a report by Verizon, only 3% of targeted users report malicious emails to management. With compan…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

830 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