2014-01-15 4 views
0

이 코드를 작성하여 애플리케이션에 직렬 포트 읽기 쓰기를 시뮬레이트했습니다.시리얼 포트 시뮬레이션 및 데이터 수신

3 밀리 초마다 데이터를 보내고 보내기 전에 데이터를 차트와 파일에 기록합니다. 또한 데이터를 보낸 후 차트의 데이터를 묘사하고 데이터를 파일에 기록하기 위해 DataRecieved 함수가 호출됩니다.

하지만 I는 어떤 점에서 잘못된 결과를 나타내고, 또한 각 3 밀리 초를 실행할 수 없습니다 실행할 경우. (때로는 매 6 1000 분의 1 초, ...는, 출력 및 입력 파일이 첨부되어있다)

또한 때로는 파일에 쓸 줄에이 오류가 발생합니다.

개체 참조가 개체의 인스턴스로 설정되지 않았습니다.

문제를 해결하려면 어떻게해야합니까?

class SignalControllerSimulator 
{ 
     public SignalControllerSimulator(SignalReaderSimulator reader, SignalWriterSimulator writer, LineSeries PitchInputLine, LineSeries RollInputLine, LineSeries YawInputLine, LineSeries PitchOutputLine, LineSeries RollOutputLine, LineSeries YawOutputLine) 
     { 
      .... 
       //do some initialization 

      SentFileLogger = new WriteFileLogger(SentFolderName); 
      RecFileLogger = new ReadFileLogger(RecFolderName); 
      SentFileLogger.Open(true); 
      RecFileLogger.Open(true); 

      rampTime = SenarioTime = SineTime = StepTime = 320;//1000ms 
      reader.DataReceived += DataReceived; 
     } 
    #region readSection 
    ObservableCollection<ChartItem> PitchInputItems = new ObservableCollection<ChartItem>(); 
    ObservableCollection<ChartItem> RollInputItems = new ObservableCollection<ChartItem>(); 
    ObservableCollection<ChartItem> YawInputItems = new ObservableCollection<ChartItem>(); 

    int PitchIndex = 1; int RollIndex = 1; int YawIndex =1 ; 

    public void DataReceived(ReadSignal signal) 
    { 

     this.PitchInputLine.Dispatcher.Invoke(new Action(() => 
     { 
      PitchInputItems.Add(new ChartItem(signal.PitchLocation, PitchIndex++)); 
      RollInputItems.Add(new ChartItem(signal.RollLocation, RollIndex++));    
      YawInputItems.Add(new ChartItem(signal.YawLocation, YawIndex++)); 
      PitchInputLine.ItemsSource = PitchInputItems; 
      RollInputLine.ItemsSource = RollInputItems; 
      YawInputLine.ItemsSource = YawInputItems; 
     })); 
      RecFileLogger.Write(true, signal.PitchLocation, signal.RollLocation, signal.YawLocation, DateTime.Now.ToString("h:m:s:fff")); 

    } 

    public void Stop() 
    { 
     ... 
    } 
    #endregion 
    #region writeSection 

    public void StartSendingLocations() 
    { 

     EndIndex = setEndIndex(); 
     timer = new System.Timers.Timer(interval); 
     timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed); 
     timer.Start(); 
    } 
    void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
    { 
     if (Index>=EndIndex) 
     { 
      Stop(); 
      return; 
     } 
     ... 
     // some switch case and function calling... 
      CreateCommand(); 
     //setting reader settings 


      //log to file the data sent: 
      SentFileLogger.Write(true, writer.WSignal.PitchLocation,       writer.WSignal.PitchAngularVelocity, writer.WSignal.RollLocation, 
        writer.WSignal.RollAngularVelocity, writer.WSignal.YawLocation, writer.WSignal.YawAngularVelocity, 
        DateTime.Now.ToString("h:m:s:fff")); 
      SignalWriter_DataSent(writer.WSignal); 
      TimeWriter.WriteLine("end:------------>" + DateTime.Now.ToString("h:m:s:fff")); 
      TimeWriter.WriteLine(); 

      reader.ThreadMain(reader.RSignal); 


      Index++; 
    } 

    ObservableCollection<ChartItem> PitchOutputItems = new ObservableCollection<ChartItem>(); 
    ObservableCollection<ChartItem> RollOutputItems = new ObservableCollection<ChartItem>(); 
    ObservableCollection<ChartItem> YawOutputItems = new ObservableCollection<ChartItem>(); 

    int PitchIndex1 = 1; int RollIndex1 = 1; int YawIndex1 = 1; 

    void SignalWriter_DataSent(WriteSignal signal) 
    { 
     RollInputLine.Dispatcher.Invoke(new Action(() => 
     { 
      PitchOutputItems.Add(new ChartItem(signal.PitchLocation, PitchIndex1++)); //PitchOutputItems.Add(new ChartItem(signal.PitchLocation, interval * PitchIndex1++)); 
      RollOutputItems.Add(new ChartItem(signal.RollLocation,RollIndex1++)); //RollOutputItems.Add(new ChartItem(signal.RollLocation, interval * RollIndex1++)); 
      YawOutputItems.Add(new ChartItem(signal.YawLocation,YawIndex1++)); //YawOutputItems.Add(new ChartItem(signal.YawLocation, interval * YawIndex1++)); 
      PitchOutputLine.ItemsSource = PitchOutputItems; 
      RollOutputLine.ItemsSource = RollOutputItems; 
      YawOutputLine.ItemsSource = YawOutputItems; 
     })); 
    } 

    private int setEndIndex() 
    { 
     return EndTime/interval; 
    } 

}

첨부 파일 :

data Receiving file

data sending file

time between sendings

+0

이런 종류의 시뮬레이션이 필요하지 않습니까? 호출 한 후에 데이터가 변경되면 코드에서 멀티 스레딩 버그가 발생합니다. 직렬 포트를 사용하는 것과 마찬가지로 예측할 수없는 타이밍을 처리 할 수 ​​있습니까? 수신 바이트의 수를 예측할 수 없게함으로써이를 향상 시키면 Random 클래스가 유용합니다. 버그를 숨기는 인식 타이머 문제를 해결하려고 시도하지 마십시오. –

답변

1

당신은 .NET 타이머에서 3 MS 해상도를 얻을 수 없습니다. 예를 들어 Why are .NET timers limited to 15 ms resolution?을 참조하십시오.

정확도가 중요한 경우 Thread.Sleep (큰 정확도는 아님) 또는 Thread.SpinWait으로 산출되는 전용 스레드를 사용할 수 있습니다.

+0

하지만 100ms에도 제대로 작동하지 않습니다. – abdolah