COMport.Readline() 问题:溢出缓冲区和字符串操作

COMport.Readline() Issues : Flooded buffer and string manipulation

我有一个体重秤,可以将恒定输出输出到串行端口。我制作了一个每 3 秒循环一次以读取秤上最新重量的应用程序,该循环使用 Async Sub,然后使用 Await Task.Run(Sub() 然后休眠 3 秒。我有 2 个问题。

首先,缓冲区充满了数据,因此如果您减轻重量,比如 100 磅,它仍会读取缓冲区中的旧数据,同时秤上的实际重量为 0。但它会慢慢下降3 秒。我尝试在 Backgroundworker 中连续循环 readline() 但比例仍然输出很快。我应该在 readline() 之前尝试 'DiscardBuffer()' 吗?还是有别的阅读方法?

代码:COM 端口属性

    With COMScale 'COM Port Properties

        .PortName = cmbPorts.Text 'COM Port Name

        .Parity = IO.Ports.Parity.None

        .DataBits = 8

        .StopBits = IO.Ports.StopBits.One

        .BaudRate = 9600

        .ReceivedBytesThreshold = 1

        .NewLine = vbCr

        .ReadTimeout = 5000

    End With

代码:后台工作人员

Private Sub BackgroundWorker1_DoWork(sender As Object, e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork

    WeightA = 0

    COMScale.DiscardInBuffer()

    Try

        COMScale.ReadTimeout = 10000

        Do

            Dim Incoming As String = COMScale.ReadLine()

            If Incoming Is Nothing Then

                Exit Do

            Else

                WeightA &= Incoming

            End If

        Loop

    Catch ex As TimeoutException

        WeightA = "N/A"

        MsgBox(COMScale.PortName & "Timed Out")

    Finally

        'If com1 IsNot Nothing Then com1.Close()

        lblWeightA.Text = WeightA

    End Try

End Sub

第二期是秤输出的字符串,像这样...

“5?” & ChrW(2) & ChrW(2) & "??j" & ChrW(2) & "; 47" & ChrW(2) & ChrW(2) & ChrW(2) & ChrW(2) & "?? j" & ChrW(2) & "; 475" & ChrW(2) & ChrW(2) & ChrW(2) & "??j" & ChrW(2) & "; 475 00"

体重秤上写着 47.5 磅

我只需要末尾的“475”数字但带有小数点,因此字符串为 47.5 。我唯一能想到的是 Right(string) 我在使用 Right(String) 时看到的问题是它可能是 1000 磅、100 磅或 10 磅,所以它会切断我需要的东西。我最好的选择是什么?

您的应用程序不应休眠 3 秒,而应连续读取。那么缓冲区将不会填满。

因此,让您的 BackgroundWorker 运行 进入一个循环。也不要修改后台工作人员的任何 UI 元素。而是使用 ReportProgress 将其发送到表单。

Private Sub BackgroundWorker1_DoWork(sender As Object, e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    COMScale.DiscardInBuffer()
    Dim buffer As String
    While e.Cancel = False

        Try

            buffer &= COMScale.ReadLine()

            buffer = ProcessBuffer(buffer)

        Catch ex As TimeoutException
            BackgroundWorker1.ReportProgress(0, ex)
        End Try

    End While
End Sub

Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
    If TypeOf e.UserState Is TimeoutException Then
        lblWeightA.Text = "N/A"
        MessageBox.Show("Timeout")
    ElseIf TypeOf e.UserState Is Decimal Then
        lblWeightA.Text = CDec(e.UserState).ToString()
    End If
End Sub

Private Function ProcessBuffer(inputBuffer As String)
    'Parse your string. Looking for the last occurrence of the data you need.

    If extractedPortion IsNot Nothing 
        BackgroundWorker1.ReportProgress(0, Decimal.Parse(extractedPortion))
    End If

    Return leftOverChacters
End Function