2014-01-15 43 views
0

我已經寫了這段代碼來模擬串口讀取應用程序的寫入。模擬串口發送和接收數據

我想每3毫秒發送一次數據,發送前我將數據記錄到圖表和文件中。在發送數據之後,也會調用DataRecieved函數來描述圖表上的數據並將數據記錄到文件中。

但是當我執行它示出了在某些點錯誤的結果,並且還它不能被每3毫秒執行。(有時每6 milisecond,...,輸出和輸入的文件附接)

還有時會在我寫入文件的行上拋出此錯誤:

未將對象引用設置爲對象的實例。

我能做些什麼來解決它?

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毫秒的分辨率。例如見Why are .NET timers limited to 15 ms resolution?

如果準確性非常重要,您可以使用專用線程,該專用線程可產生Thread.Sleep(同樣精度不高),或可能使用Thread.SpinWait

+0

,但即使100ms也不能正常工作。 – abdolah