2014-01-15 4 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

Вы не сможете получить разрешение 3 мс от таймера .NET. Например, см. Why are .NET timers limited to 15 ms resolution?.

Вы можете использовать выделенный поток, который дает Thread.Sleep (также не очень высокую точность) или, возможно, Thread.SpinWait, если точность действительно важна.

+0

, но он не работает нормально даже на 100 мс. – abdolah

 Смежные вопросы

  • Нет связанных вопросов^_^