Link to home
Start Free TrialLog in
Avatar of hawkeen
hawkeen

asked on

serial port vb.net 2005 loop problem

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
ASKER CERTIFIED SOLUTION
Avatar of Jeff Certain
Jeff Certain
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of hawkeen
hawkeen

ASKER

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
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)
Avatar of hawkeen

ASKER

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
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?
Avatar of hawkeen

ASKER

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