직렬 포트 readline vs readexisting 또는 직렬 포트에서 데이터를 올바르게 읽는 방법
-
10-07-2019 - |
문제
직렬 포트에서 데이터를 읽고 있습니다. 데이터는 규모에서 벗어납니다. 나는 지금 사용하고있다 Readline()
그리고 제거 후에도 데이터가 삭제됩니다 DiscardInBuffer()
. 직렬 포트에서 데이터를 읽는 올바른 방법은 무엇입니까? 온라인으로 사례가 거의 없어서 아무도 알아 내지 못한 성배와 같다고 생각합니다.
도와주세요?
일련의 항구는 변덕스러운 아이 인 것 같습니다.
C#, Wince 5.0, HP 씬 클라이언트, 소형 프레임 워크 2.0
private void WeighSample()
{
this._processingDone = false;
this._workerThread = new Thread(CaptureWeight);
this._workerThread.IsBackground = true;
this._workerThread.Start();
} //end of WeighSample()
private void CaptureWeight()
{
globalCounter++;
string value = "";
while (!this._processingDone)
{
try
{
value = this._sp.ReadLine();
if (value != "")
{
if (value == "ES")
{
_sp.DiscardInBuffer();
value = "";
}
else
{
this.Invoke(this.OnDataAcquiredEvent, new object[] { value });
}
}
}
catch (TimeoutException)
{
//catch it but do nothing
}
catch
{
//reset the port here?
MessageBox.Show("some other than timeout exception thrown while reading serial port");
}
}
} //end of CaptureWeight()
내 응용 프로그램에 대해 주목해야 할 한 가지는 커서가 텍스트 상자로 점프 할 때 스레드 (무게 샘플)를 시작한다는 것입니다. 그 이유는 무게를 수동으로 입력 할 수 있기 때문입니다 (REQ의 일부). 따라서 사용자가 균형에 인쇄를 누르거나 무게를 입력 할 것인지 미리 알 수 없습니다. 두 경우 모두 데이터를 획득 한 후에는 작업자 스레드를 종료합니다. 또한, 나는 신뢰할 수 없다고 들었 기 때문에 Serial Port 이벤트를 사용하지 않는다는 점에 유의하십시오.
모든 의견/ 아이디어를 환영합니다. 이것은 직렬 포트에 대한 첫 경험입니다.
해결책
나는 가지고있다 절대 Readline 작업으로 운이 좋았습니다. 데이터를 사용할 수있을 때마다 로컬 버퍼를 읽은 다음 별도의 스레드를 사용하여 데이터를 스캔하고 라인이 직접 파손됩니다.
다른 팁
입력 데이터에 대한 종말 (EOL) 문자가 무엇인지에 따라 다릅니다. 데이터 데이터가 라인 방향 인 경우 읽기 라인은 사용하기에 유효한 기능이지만 Newline 속성을보고 입력 데이터에 적절하게 설정되어 있는지 확인하십시오.
예를 들어, 스케일이 EOL의 LineFeed를 출력하는 경우 port.NewLine = "\n";
http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.newline.aspx
Elias Santos에게 댓글을 달고 싶지만 명성이 충분하지 않습니다. ReadExisting 메소드를 사용하는 데는 일부 gotchas가 있습니다.
https://msdn.microsoft.com/en-us/library/system.io.ports.serialport.readexisting(v=vs.110).aspx
이 방법은 내부 버퍼에 후행 리드 바이트를 남길 수 있으므로 바이 테스토리드 값이 0보다 크게 높아집니다.
나는 이전에 ReadExisting과 관련하여 몇 가지 문제에 직면했으며 이것은 원치 않는 바이트 때문입니다. Readline을 사용하면 해당 문제가 해결되었습니다.
if (serialPort1->IsOpen){
if (serialPort1->BytesToRead>0){
this->textBox1->Text += serialPort1->ReadExisting();
}
}