2012-05-30 8 views
0

직렬 포트를 통해 컴퓨터에 스케일을 인터페이스합니다. 루프 내에서 0에 도달하면 SerialPort.BytesToRead 값을 확인합니다. 하지만 BytesToRead가 0이 아니더라도 루프가 종료됩니다. 새 사용자이므로 디버그를 통해 실제로 0이 아닌 화면을 볼 수 있습니다.SerialPort.BytesToRead가 0이 아닌 경우에도 항상 0으로 평가됩니다.

이 결과로 my 데이터가 완전히 읽히지 않습니다. 나는 _port.BytesToRead > 0과 같은 다른 표현식을 시도했지만 그 결과는 같습니다. BytesToRead의 값을 변수에 할당하더라도 루프가 없으면 ReadExisting은 척도에서 보낸 모든 데이터를 반환하지 않으므로 선택 사항이 없습니다. ReadLine도 작동하지 않습니다. BytesToRead가 항상 0 인 이유는 무엇입니까? 디버거없이 실행되므로 더 브레이크 포인트가 발생되지 않을 때 당신이, 읽을 사실 바이트에 있다는 것을 충분히 느린거야 디버거를 실행하지만 때

private void PortDataReceived(object sender, SerialDataReceivedEventArgs e) 
    { 
     { 
      var input = string.Empty; 
      // Reads the data one by one until it reaches the end 
      do 
      { 
       input += _port.ReadExisting(); 
      } while (_port.BytesToRead != 0); 

      _scaleConfig = GenerateConfig(input); 

      if (ObjectReceived != null) 
       ObjectReceived(this, _scaleConfig); 
     } 
    } 
+0

이것은 일반적인 문제이며 디버깅 아티팩트입니다. 코드가 작동하지 않을 수 있습니다. 응답의 모든 바이트가 있는지 확인하지 못합니다. 일반적으로 ReadLine()은 NewLine 속성이 척도가 전송하는 것과 일치하는 경우 작동합니다. –

+0

문제는 저울이 한 번에 여러 줄의 데이터를 보내서 모든 줄을 얻기 위해 루프 안에 보관해야한다는 것입니다. 내가 데이터의 끝까지 도달했는지 어떻게 알 수 있을까? 이 코드를 변경하지 않고도 스케일을 변경할 수 있도록 일반화하려고합니다. – NTHQ

답변

2

내 상사가 알아 냈습니다. 여기에 코드가 있습니다. 코드는 코드가 그것을 비워 때문에, 또는 장치가 아직 전송되지 않았기 때문에 버퍼가 비어있는 경우 아는 어쨌든 볼 수 없기 때문에

private void PortDataReceived2(object sender, SerialDataReceivedEventArgs e) 
    { 
     var bytesToRead = _port.BytesToRead; 
     _portDataReceived.Append(_port.ReadExisting()); 

     // Buffer wasn't full. We are at the end of the transmission. 
     if (bytesToRead < _port.DataBits) 
     { 
      //Console.WriteLine(string.Format("Final Data received: {0}", _portDataReceived)); 
      IScalePropertiesBuilder scaleReading = null; 

      scaleReading = GenerateConfig(_portDataReceived.ToString()); 
      _portDataReceived.Clear(); 


      if (ObjectReceived != null) 
      { 
       ObjectReceived(this, scaleReading); 
      } 
     } 
    } 
1

아마도, 그것은 전에 루프를 종료 끝 직렬 포트의 장치에 데이터를 보낼 시간이 있습니다. 대부분의 경우 ReadExisting은 포트의 모든 데이터를 읽은 다음 포트에 새로운 데이터가 없으므로 즉시 종료합니다. 아마도 문제를 완화하기 위해 데이터 읽기와 BytesToRead의 값을 검사하여 더 많은 데이터가 있는지 확인하는 사이에 작은 대기 (아마도 Thread.Sleep())를 넣을 수 있습니다. 당신이 읽으려고하는 데이터를보고 있으면 그것이 필요한 모든 데이터를 읽었을 때를 결정할 수 있습니다.

+0

데이터를 읽기 전에 Thread.Sleep()을 넣는 것은 효과가 있지만 효율성을 위해이 작업을 수행하지 않으려 고합니다. 내가 지금 사용하고있는 척도의 경우, 나는받는 데이터의 끝을 쉽게 알아낼 수 있지만 가능한 한 추상적으로 만들고 싶습니다. 그래서 척도를 변경해야한다면이 코드를 변경할 필요가 없습니다. . – NTHQ

2

원래 코드는 이상했다. (이것은 당신의 디자인에서 근본적인 문제로 보인다 : 당신은 모든 바이트를 얻을 때까지 읽길 원하지만, 모든 바이트를 읽은 후에야 몇 바이트가 있어야만하는지 알 수있다).

DataBits가 바이트 당 비트 수 (5와 8 포함)의 직렬 구성이기 때문에 나중에 코드가 더 낯선 경우가 있습니다. RS232에서만 바이트가 8 비트 미만일 수 있습니다.

그건 그렇고, 내가 BytesToRead 주위에 아주 이상한 행동을보고있다. 그것은 거의 완전하게 신뢰할 수없고 유용한 후에 만 ​​업데이트해야한다는 생각이 듭니다. MSDN에 일관성이 없다는 내용의 메모가 있습니다. 그러나 그 내용은 설명 할 수없는 0도 포함되어 있지 않습니다.

관련 문제