2016-08-12 1 views
1

직렬 포트에 일정한 출력을 갖는 체중 눈금이 있습니다. 나는 3 초마다 루프를 실행하여 저울에서 가장 최근의 무게를 읽는 응용 프로그램을 만들었습니다. 루프는 Async Sub를 사용하고 Await Task.Run(Sub()은 3 초 동안 대기합니다. 나는 2 가지 이슈를 가지고있다.COMport.Readline() 문제 : 플러딩 된 버퍼 및 문자열 조작

첫째, 버퍼가 데이터로 넘쳐 흐르고 있으므로 100 파운드라고 말하면 버퍼에서 이전 데이터를 읽지 만 실제 저울의 무게는 0입니다. 그러나 천천히 내려갑니다 초. 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 

코드 : BackgroundWorker에 두 번째 문제는 스케일 출력, 그것은 다음과 같이 좋아하는 문자열입니다

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 

...

"오?" & 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.5lbs입니다.

끝에는 "475"숫자가 필요하지만 십진수는 47.5입니다. 내가 생각할 수있는 유일한 것은 Right(String)을 사용하여 볼 수있는 Right(string) 문제입니다. 1000 파운드, 100 파운드 또는 10 파운드가 될 수 있으므로 필요한 부분을 잘라 버릴 수 있습니다. 내 최선의 선택은 뭐니?

+0

는 읽기는 각 읽기 후에 캐리지 리턴 또는 줄 바꿈 이 있습니까? 전체 메시지를 가져올 때까지 문자열을 만들어야합니다. datarecieved 이벤트는 다소 임의적으로 발생하며 때때로 전체 문자열의 일부만 가져옵니다. 스트림이 완료된 시점을 알기 위해서는 char을 해제해야합니다. 일반적으로 콜백 함수 또는 [대리인] (https://msdn.microsoft.com/en-us/library/ms172879.aspx)을 사용합니다. 대부분의 경우 은 스트림의 끝을 의미합니다. 그런 다음 응답을 처리하기 위해 내 대리자 기능을 시작합니다. – Baddack

+0

두 번째 부분에서는';'에 문자열'Split'을 수행하십시오. 문자열을 각 세미콜론에 대한 문자열 배열로 분할 한 다음 47500에 대한 마지막 레코드를 구문 분석 할 수 있습니다. 배율에 대한 설명서를 읽으십시오. 그러나 해당 값을 구문 분석하고 1000으로 나눌 수 있어야합니다. – Baddack

+0

'newline = vbCr'을 사용하면 그것이 무엇을 의미합니까? 새로운 시리얼 포트를 사용합니다. 만약 내가 그것을 사용하지 않는 표시 데이터가 없습니다. – holi4683

답변

0

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 
+0

내가 일할 때 나는이 월요일을 시험 할 것이다. – holi4683

+0

오, 내가 3 초를 기다리는 이유는 체중이 바뀐 후에 체중이 안정 될 필요가 있기 때문이며, 나는 논리 문제 때문에 더 이상 사용하지 않을 것입니다. – holi4683

+0

나는 당신의 코드와 msdn 사이에서 작동하도록했다. 나는 한 가지 예를 통해 'Me. 백 그라운드 스레드를 시작하려면 BackgroundWorker1.RunWorkerAsync (2000) '명령을 사용하십시오. 2000 년의 의미를 아십니까? – holi4683