2012-11-26 5 views
2

시리얼 포트를 통해 주기적으로 데이터를 받고 있습니다. 이러한 목적을 달성하기 위해 각 마이크로 컨트롤러의 데이터를 각 패킷의 길이를 지정하는 헤더와 함께 내 컴퓨터로 보냅니다.시리얼 포트로부터 패킷을 기다리는 것을 멈추십시오.

마지막 세부 사항을 제외하고 프로그램을 실행하고 완벽하게 작동합니다. 헤더가 길이를 지정하면, 프로그램은 그 바이트 수에이를 때까지 멈추지 않습니다. 어떤 이유로 한 패킷의 일부 데이터가 누락되면 프로그램이 대기하고 다음 패킷의 시작을 가져온 다음 실제 문제를 시작합니다. 그 순간 이후 모든 것이 실패합니다.

나는 타이머를 0.9 초마다 올리려고 생각했다. (패키지는 매 초마다 온다.) 누가 변수를 기다리고 다시 설정하기 위해 명령을 내릴지를 명령했다. 그러나 나는 그것을하는 방법을 모른다, 나는 시도했다. 그러나 나는 달리면서 오류를 얻는다. IndCom (다음 코드 참조)은 일부 기능 및 오류의 중간에 "범위를 벗어난 색인"이 재설정되기 때문에 재설정됩니다.

나는

private void routineRx(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) 
    { 
     try 
     { 
      int BytesWaiting; 


      do 
      { 
       BytesWaiting = this.serialPort.BytesToRead; 
       //Copy it to the BuffCom 
       while (BytesWaiting > 0) 
       { 
        BuffCom[IndCom] = (byte)this.serialPort.ReadByte(); 
        IndCom = IndCom + 1; 
        BytesWaiting = BytesWaiting - 1; 
       } 

      } while (IndCom < HeaderLength); 
      //I have to read until I got the whole Header which gives the info about the current packet 

      PacketLength = getIntInfo(BuffCom,4); 

      while (IndCom < PacketLength) 
      { 
       BytesWaiting = this.serialPort.BytesToRead; 
       //Copy it to the BuffCom 
       while (BytesWaiting > 0) 
       { 
        BuffCom[IndCom] = (byte)this.serialPort.ReadByte(); 
        IndCom = IndCom + 1; 
        BytesWaiting = BytesWaiting - 1; 
       } 
      } 

      //If we have a packet--> check if it is valid and, if so, what kind of packet is 
      this.Invoke(new EventHandler(checkPacket)); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message); 
     } 

    } 

내가 객체 지향 프로그래밍 및 C#에서 새로운, 그래서, 클레멘트주세요 (타이머없이) 내 코드를 첨부! 그리고 대단히 감사합니다

+0

** 어떤 이유로 인해 한 패킷의 일부 데이터가 누락 된 경우 ** : 문제를 해결하기 전에 문제를 해결할 수 있습니다. 데이터가 누락 된 이유는 무엇입니까? μC가 전송하지 않거나 앱이 어떤 이유 때문에이를 버렸습니까? – igrimpe

+0

사실이라면, 나는 잘못된 패킷 (실제보다 더 긴 길이의 패킷)을 보내는 상황을 강요하고 있습니다. 나는 하나의 패킷이나 싱글 바이트를 놓친 적이 없다. 그러나 이것은 GPRS 응용 프로그램을 구현하는 첫 번째 단계이며 데이터 손실 가능성이 높아집니다. 시리얼 포트를 통해 먼저 프로그램을 테스트하고 있지만, 이런 종류의 문제에 직면 할 수있는 강력한 프로그램이 필요합니다. – Ger

답변

0

당신이 처음에 Stopwatch.

const long COM_TIMEOUT = 500; 

Stopwatch spw = new Stopwatch(); 
spw.Restart(); 
while (IndCom < PacketLength) 
{ 
    //read byte, do stuff 
    if (spw.ElapsedMilliseconds > COM_TIMEOUT) break; //etc 
} 

재시작 스톱워치를 사용하여 각 시간을 확인 루프, 후 탈출하면서 (및 청소) 시간 제한이있는 경우입니다 할 수 있습니다 안타. 몇 바이트 만 예상하면 900ms는 너무 많습니다. 컴 트래픽은 꽤 빠릅니다. 즉, 모든 것을 즉시 얻지 못하면 아마 오지 않을 것입니다.

저는 통신 프로토콜 (예 : [CR] 등)에 종료 문자를 사용하는 것을 좋아합니다. 이렇게하면 종료 문자를 찾을 때까지 읽을 수 있습니다. 이렇게하면 다음 명령을 읽을 수 없습니다. 다음 라운드에 대해 버퍼에 남아있는 문자를이 수

while (IndCom < PacketLength) 
{ 
    if (serialPort.BytesToRead > 0) 
    { 
     BuffCom[IndCom] = (byte)this.serialPort.ReadByte(); 
     IndCom++;    
    } 
    } 

당신이 당신의 패킷 크기에 도달 할 때 중지 떠나 :이 같은 당신의 코드를 변경, 종료 문자를 사용하지 않는 경우에도 through (즉, 다음 명령). 위의 경우에도 스톱워치 제한 시간을 추가 할 수 있습니다.

종료 문자에 대한 또 다른 좋은 점은 패킷이 얼마나 오래 있어야하는지 미리 알 필요가 없다는 것입니다. 사용자가 종료 문자에 도달 할 때까지 읽은 다음 모든 것을 처리/구문 분석하면 알았다. 2 단계 포트 읽기를 1 단계 포트 읽기로 만듭니다.

+0

스톱워치를 사용해 보았는데 효과적입니다. timeelapsed 또한 IndCom 및 기타 변수를 재설정해야 함). 그러나 잘 작동합니다. :) 대단히 감사합니다. J ... – Ger

관련 문제