0

I'm pretty new at programming, and .net is the what I use to do the easy stuff I need. I created a program to read from a weight indicator that comes through the serial port and it was working just fine like this for an EL05 device:

Private Sub sppuerto_DataReceived( sender As Object, e As IO.Ports.SerialDataReceivedEventArgs ) Handles sppuerto.DataReceived

    Dim buffer As String
    '------- WORKS FOR EL05 -----------------
    buffer = sppuerto.ReadLine
    txtrecibe.Text = buffer.Substring(4, 5)
End Sub

But now I'm connecting a new device from another manufacturer and I get an exception with ReadLine:

An unhandled exception of type 'System.IO.IOException' occurred in System.dll

Additional information: La operación de E/S se anuló por una salida de subproceso o por una solicitud de aplicación"

The English version of the exception message is

The I/O operation has been aborted because of either a thread exit or an application request


I got it to work with ReadExisting but it keeps reading and never stops like it did with ReadLine

Private Sub sppuerto_DataReceived( sender As Object, e As IO.Ports.SerialDataReceivedEventArgs ) Handles sppuerto.DataReceived

    Dim buffer As String

    '------------- WORKS WITH NEW INDICATOR BUT UNREADABLE----------------
    buffer = sppuerto.ReadExisting
    txtrecibe.Text = buffer

End Sub

I looked around but all the posts refer to C# implementations and I really don't want to get into that since is completely different for what I read. Also in Java.

Has anyone tried this in VB.NET? I can paste more of the code if needed.

Edit: Adding the complete code by request (not really that long)

Imports System.IO.Ports

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        CheckForIllegalCrossThreadCalls = False
        buscarpuerto()
    End Sub

    Private Sub buscarpuerto()

        Try
            cmbPort.Items.Clear()
            For Each puerto As String In My.Computer.Ports.SerialPortNames
                cmbPort.Items.Add(puerto)
            Next
            If cmbPort.Items.Count > 0 Then
                cmbPort.SelectedIndex = 0

            Else
                MsgBox(" NO HAY PUERTO DISPONIBLES ")
            End If
        Catch ex As Exception
            MsgBox(ex.Message, MsgBoxStyle.Critical)
        End Try

    End Sub

    Private Sub btnconectar_Click(sender As Object, e As EventArgs) Handles btnconectar.Click
        Try
            With sppuerto
                .BaudRate = Int32.Parse(CboBaudRate.Text)
                .DataBits = 8
                .Parity = IO.Ports.Parity.None
                .StopBits = 1
                .PortName = cmbPort.Text
                .Open()

                If .IsOpen Then
                    lblestado.Text = "CONECTADO"
                Else
                    MsgBox("NO SE PUDO CONECTAR", MsgBoxStyle.Critical)
                End If


            End With
        Catch ex As Exception

        End Try
    End Sub

    Private Sub btndesconectar_Click(sender As Object, e As EventArgs) Handles btndesconectar.Click
        sppuerto.Close()
        lblestado.Text = "DESCONECTADO"
    End Sub

    Private Sub sppuerto_DataReceived(sender As Object, e As IO.Ports.SerialDataReceivedEventArgs) Handles sppuerto.DataReceived

        Dim buffer As String
        Dim x As String
        buffer = ""

        '------- WORKS FOR EL05 -----------------

        'buffer = sppuerto.ReadLine
        'txtrecibe.Text = buffer.Substring(4, 5)


        '------------- WORKS WITH NEW INDICATOR BUT UNREADABLE----------------
        x = sppuerto.ReadExisting
        buffer = buffer + x
        txtrecibe.Text = buffer


    End Sub

    Private Sub btnenviar_Click(sender As Object, e As EventArgs) Handles btnenviar.Click
        If sppuerto.IsOpen Then
            sppuerto.WriteLine(txtenvia.Text)
        Else
            MsgBox("NO ESTAS CONECTADO", MsgBoxStyle.Exclamation)
        End If
    End Sub

    Private Sub btnsalida_Click(sender As Object, e As EventArgs) Handles btnsalida.Click
        If lblestado.Text = ("CONECTADO") Then
            MsgBox("DESCONECTARSE DEL SISTEMA", MsgBoxStyle.Exclamation, "AYUDA")
        Else
            Close()
        End If
    End Sub
End Class
jal2305
  • 1
  • 1
  • Strings are not buffers. – Dai Dec 21 '21 at 22:28
  • What is an "EL05 device" ? – Dai Dec 21 '21 at 22:28
  • You're using `SerialPort` incorrectly. The `DataReceived` event should only be used with the `ReadExisting()` method, you should not perform any blocking calls inside the `_DataReceived` event-handler. – Dai Dec 21 '21 at 22:34
  • "Also in Java." - Java is **completely different** (not only a different language, but a completely different API design and serial-port library), at least with C# code examples you're using the same library (`System.IO.Ports`) so the answers and examples for those are translatable to VB.NET. – Dai Dec 21 '21 at 22:36
  • Also, out of curiosity, why are you using VB.NET when Microsoft has made it unambiguously clear that VB.NET won't be part of the .NET ecosystem in the near future? – Dai Dec 21 '21 at 22:36
  • We can't really help you without seeing the specification of the serial-port protocol you're trying to use. – Dai Dec 21 '21 at 22:38
  • We need to see your entire program, or at least **all** of your `Form` subclass that owns/manages your `sppurto` object. – Dai Dec 21 '21 at 22:39
  • Hi Dai! Thanks for the replies. So trying to answer: I use VB.NET because it's what I know XD . It's curious that you say that I should only use ReadExisting, it worked with ReadLine so far... Anyways you know well better than I do. Here is the complete Form, it's not that large of a code (in an answer because I ran out of chars) – jal2305 Dec 21 '21 at 22:46
  • Don't post code in comments; edit your question-post instead. And use backticks `\``, not apostrophes, for code-blocks. – Dai Dec 21 '21 at 22:49
  • The following may be helpful: https://stackoverflow.com/questions/68323803/vb-net-weight-scale-reading/68332588#68332588 and https://stackoverflow.com/questions/69943909/unable-to-decode-serial-port-data/69946343#69946343 – Tu deschizi eu inchid Dec 21 '21 at 23:58

1 Answers1

0

I suspect that with your new device, the data is NOT completely received. You may need to test the incoming data buffer to see if its length is still increasing. Only do you ReadExisting if the device is done sending data into the buffer.

Dim x = SerialPort1.BytesToRead

Application.DoEvents()

Do While SerialPort1.BytesToRead <> x
     x = SerialPort1.BytesToRead
     Application.DoEvents()
Loop

Beware that this will block your code from running until the device is done writing. Also, if your computer is slow, and the COM device is continuously sending data, you may get a new string in the buffer before the BytesToRead numbers can be compared and NEVER break out.

You may also want to change your ReceivedBytesThreshold for the serial port to only fire the DataReceived event if several bytes have been received instead of the default one byte.