串口打开和读取输入之间的延迟

时间:2016-11-22 14:20:38

标签: c# serial-port

我有一个通过USB连接到串口的刻度(但我也使用过直接串口并遇到过这个问题) 我启动我的应用程序并打电话给SerialPort.Open并且它打开正常,根据电话...但是,当我按照附加的比例推送打印时,我没有得到我设置的队列中的任何内容。然后,大约20-30秒后,我能够推送打印,所有打印都很好。 为了增加混乱,我可以随时通过同一个端口打开并打印到PuTTy。 显然我的代码中缺少一些东西。这里的Output队列带有在程序打开时设置的观察者:

public class Scan_Output_Queue<T> : AFGObservableAFGObserver<T,T>, IEnumerable<T>
{
    private ConcurrentQueue<T> _Queue;

    public Scan_Output_Queue()
    {
        _Queue = new ConcurrentQueue<T>();
    }

    public T Dequeue()
    {
        T item = default(T);
        _Queue.TryDequeue(out item);
        return item;
    }
    public void reinsert(T item)
    {
        Queue<T> queueCopy = new Queue<T>(_Queue.ToArray());
        T junk = default(T);
        foreach (T weight in queueCopy)
        {
            _Queue.TryDequeue(out junk);
        }
        _Queue.Enqueue(item);
        foreach (T weight in queueCopy)
        {
            _Queue.Enqueue(weight);
        }
        base.redraw_Send();
    }
    public void Enqueue(T Item)
    {
        _Queue.Enqueue(Item);
    }

    public T Peek()
    {
        T item = default(T);
        _Queue.TryPeek(out item);
        return item;
    }

    protected override T Receive(T value)
    {
        Enqueue(value);
        return value;
    }



    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        return _Queue.GetEnumerator();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return _Queue.GetEnumerator();
    }


}

我在这里放置断点,但在20-30秒的标记处没有任何'神奇'。我只能按下打印按钮,它就会填满队列。

这是请求的Scale Reader代码。这持续循环尝试打开端口20-30秒:

Public Class Scale_Reader

    Public Property Setting_Port As String
    Public Property Setting_Baud As Integer
    Public Property Setting_Parity As System.IO.Ports.Parity
    Public Property Setting_DataBits As Integer
    Public Property Setting_StopBits As Integer
    Public Property Setting_Suffix As String

    Public Property LineSeperator As String = vbCrLf
    Public Property LineSeperator As String = Setting_Suffix


    Public Sub New(ByVal sPort As String, ByVal sBaud As Integer, ByVal sPari_Str As String, ByVal sDataBits As Integer, ByVal sStopBits As Integer, sSuffix As String)
        Setting_Port = sPort
        Setting_Baud = sBaud


        Select Case sPari_Str
            Case "e"
                Setting_Parity = IO.Ports.Parity.Even
            Case "m"
                Setting_Parity = IO.Ports.Parity.Mark
            Case "n"
                Setting_Parity = IO.Ports.Parity.None
            Case "o"
                Setting_Parity = IO.Ports.Parity.Odd
            Case "s"
                Setting_Parity = IO.Ports.Parity.Space
        End Select

        Setting_DataBits = sDataBits
        Setting_StopBits = sStopBits

        If sSuffix.ToUpper() = "CR" Then
            LineSeperator = vbCr
        Else If sSuffix.ToUpper() = "CRLF" Then
            LineSeperator = vbCrLf
        Else
            LineSeperator = ""
        End If

    End Sub



    Public Property PrintString As String

    Public Property ValidExpressions As List(Of String) = New List(Of String)
    Public Property InvalidExpressions As List(Of Scale_InvalidExpression) = New List(Of Scale_InvalidExpression)

    Protected Sub Add_ValidExpression(ByVal Expression As String)
        ValidExpressions.Add(Expression)
    End Sub

    Protected Sub Add_InvalidExpression(ByVal Expression As String, ByVal ErrorMessage As String)
        Dim I As Scale_InvalidExpression = New Scale_InvalidExpression()
        I.Expression = Expression
        I.ErrorMessage = ErrorMessage

        InvalidExpressions.Add(I)
    End Sub

    Public Function ReadWeight(Optional GetMode As Integer = 1) As Scale_ReadResults

        Dim Results As Scale_ReadResults = Nothing

        For i As Integer = 1 To 3

            Results = ReadWeightPrivate(GetMode)

            If Results.Valid OrElse Results.ErrorMessage <> "" Then
                Exit For
            End If

        Next

        Return Results

    End Function


    Public Property Cancel_ConstantRead As Boolean = False

    Public Sub ReadWeightConstant(WeightRead As Action(Of Decimal))

        Using Cons_ComPort As SerialPort = New SerialPort()


            Dim ReturnWeight As Decimal = 0
            Dim data As String = ""
            Cancel_ConstantRead = False

            While Not Cons_ComPort.IsOpen 
                    InitializeComPort(Cons_ComPort)
            End While

            While Not Cancel_ConstantRead

                If Not Cons_ComPort.IsOpen Then
                    InitializeComPort(Cons_ComPort)
                End If

                Try
                    While Cons_ComPort.BytesToRead > 0
                        Dim TempData As String = Cons_ComPort.ReadExisting()
                        data += TempData
                        Threading.Thread.Sleep(10)
                    End While
                Catch ex As Exception
                     'InitializeComPort(Cons_ComPort)
                End Try



                'Find whole lines

                Dim Pos As Integer = data.IndexOf(LineSeperator)
                'Dim Pos As Integer = data.IndexOf(vbCr)

                While Pos > -1

                    Dim Line As String = data.Substring(0, Pos)

                    ReturnWeight = TestValidExpressions(Line)

                    If ReturnWeight <> 0 Then
                        'Results.Valid = True
                        'Results.ErrorMessage = ""
                        'Results.Weight = ReturnWeight
                        'Results.RawData = data
                        WeightRead.Invoke(ReturnWeight)
                    End If
                    data = data.Substring(Pos + LineSeperator.Length)
                    'data = data.Substring(Pos + 1)
                    Pos = data.IndexOf(vbCr)

                End While

                Threading.Thread.Sleep(10)
            End While

            If Cons_ComPort.IsOpen Then
                GC.ReRegisterForFinalize(Cons_ComPort.BaseStream)
                Cons_ComPort.Close()
                GC.ReRegisterForFinalize(Cons_ComPort)
            End If

        End Using

    End Sub


    Private Function ReadWeightPrivate(GetMode As Integer) As Scale_ReadResults


        Dim Results As Scale_ReadResults = New Scale_ReadResults()

        Dim ReturnWeight As Decimal = 0
        Dim Attempts As Integer = 20


        Using ComPort As SerialPort = New SerialPort()

            Try
                InitializeComPort(ComPort)
            Catch
                Dim ErrorMessage As String = "Invalid Comm Settings."
                Results.ErrorMessage = ErrorMessage
                Return Results
            End Try

            ComPort.ReadExisting()

            If GetMode = 1 Then
                ComPort.Write(PrintString)
                Attempts = 100
            End If

            Dim NumTries As Integer = 0
            Dim data As String = ""


            While NumTries < Attempts


                While ComPort.BytesToRead > 0
                    data += ComPort.ReadExisting.Replace(Chr(10), " ").Replace(Chr(13), " ")

                End While

                ReturnWeight = TestValidExpressions(data)

                If ReturnWeight <> 0 Then
                    Results.Valid = True
                    Results.ErrorMessage = ""
                    Results.Weight = ReturnWeight
                    Results.RawData = data
                    Exit While
                End If

                Dim ErrorMessage As String = TestInValidExpressions(data)
                If GetMode = 1 AndAlso ErrorMessage.Length > 0 Then
                    Results.Valid = False
                    Results.ErrorMessage = ErrorMessage
                    Results.Weight = 0
                    Results.RawData = data
                    Exit While
                End If

                Threading.Thread.Sleep(10)
                NumTries += 1

                Results.RawData = data

            End While

            ComPort.Close()
        End Using

        Return Results

    End Function


    Private Function TestValidExpressions(ByVal Data As String) As Decimal
        For Each ValidExpression As String In ValidExpressions
            Dim R As New Regex(ValidExpression)
            Dim M As Match = R.Match(Data)
            If M.Success Then
                Dim sWeight = M.Groups("Weight").Value
                Return Val(sWeight)
            End If
        Next
        Return 0
    End Function

    Private Function TestInValidExpressions(ByVal Data As String) As String
        For Each ValidItem As Scale_InvalidExpression In InvalidExpressions
            Dim R As New Regex(ValidItem.Expression)
            Dim M As Match = R.Match(Data)
            If M.Success Then
                Return ValidItem.ErrorMessage
            End If
        Next
        Return ""
    End Function
    Private Sub InitializeComPort(ByRef ComPort As SerialPort)

        ComPort.PortName = Setting_Port
        ComPort.BaudRate = Setting_Baud
        ComPort.Parity = Setting_Parity
        ComPort.StopBits = Setting_StopBits 
        ComPort.DataBits = Setting_DataBits
        ComPort.Handshake = Handshake.None
        Try
            GC.SuppressFinalize(ComPort)
            ComPort.Open()
            GC.SuppressFinalize(ComPort.BaseStream)
        Catch ex As Exception
            '    MessageWindow.Show("COM Port Error", "The COM Port cannot be opened, please check connection", MessageWindow.ButtonStyle.Ok, MessageWindow.IconStyle.Error)

        End Try

    End Sub

End Class

0 个答案:

没有答案