2012-03-01 23 views
2

現在Iamはシリアルポートを連続して読み込む必要があるプロジェクトで作業しています。データは最大45分間連続して出力されます。チェックサムを介してデータを検証し、79バイトのパケットを作成する必要があります。その後、私はリアルタイムでデータ(軌道)をプロットする必要があります。コードの問題は、起動時にCPU使用率の20%(Pentium 4,3.0 GHz、ハイパースレッディング)(これはまだ高いと思います)を使用していますが、時間とともにCPU使用率が増加し、最終的には60% 。CPU使用率が高いシリアルポートの使用時間

データは115200のボーレートで受信され、レート100ミリ秒で連続して送信されます。

読書のための私のコード、検証し、次のようにプロットがある:以下の関数は、ラベル上のデータを表示し、上の軌跡を描く

private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) 
    { 
     try 
     { 
      header1 = serialPort1.ReadByte(); 
      if (header1 == 0) 
       header2 = serialPort1.ReadByte(); 
      if ((header1 == 0) && (header2 == 1))//Store the data in an array. 
      { 
       for (int i = 0; i < 77; i++) 
        abudata[i] = serialPort1.ReadByte(); 
       tail = abudata[76]; 
      } 
      else 
      { 
       serialPort1.DiscardInBuffer(); 
      } 
      checksum = 1;// Calculate the checksum. 
      for (i = 0; i < 74; i++) 
       checksum = checksum + (abudata[i]); 
      checksum1 = (abudata[75] << 8); 
      checksum1 = checksum1 + (abudata[74]); 

      if ((checksum == checksum1) && (tail == 4)) 
       this.Invoke(new EventHandler(Display_Results));// Function to display 
     } 
     catch (Exception ode) 
     { 
      l4[4].BackColor = Color.Red; 
     } 
    } 

次の関数がデータを受信し、それを検証し...ピクチャボックス

private void Display_Results(object s, EventArgs e) 
    { 
     head1[0] = header1; 
     head1[1] = header2; 
     for (k = 0; k < 77; ++k) 
      head1[k + 2] = (((int)abudata[k]) & 0x000000ff); 
     jk = 0; 
     for (k = 0; k < 36; ++k) //Data packing into 36 bytes 
     { 
      num_1[k] = (ulong)((head1[jk + 1]) + (head1[jk] << 8)) & 0x0000ffff; 
      num_1[k] = (double)num_1[k]; 
      num_2[k] = (double)num_1[k]; 
      jk = jk + 2; 
      signbit = (int)num_1[k] >> 15; 

      if (signbit == 1) 
      { 
       sgnval = -1; 
       num_1[k] = num_1[k] - 65535; 
       num_1[k] = num_1[k] * (-1.0); 
      } 
      else 
       sgnval = 1; 

      //Converting the data into engineering values 

      engval[k] = Math.Round(num_1[k] * parammaxval[k] * sgnval/32767.0, 3); 

      if (k == 14) 
      { 
       try 
       { 

        curr_x = (pictureBox2.Width/2) + (int)((engval[13] * (pictureBox2.Width))/map_width); 
        curr_y = (pictureBox2.Height/2) - (int)((engval[14] * (pictureBox2.Height))/map_height); 
        PointF p1 = new Point(curr_x, curr_y); 
        if (_gPath != null && _gPath.PointCount > 0) 
         p1 = _gPath.PathPoints[_gPath.PathPoints.Length - 1]; 
        PointF p2 = new Point(curr_x, curr_y); 
        _gPath.AddLine(p1, p2); 
        pictureBox2.Invalidate(); 
       } 
       catch (Exception ex) 
       { 
        MessageBox.Show(ex.Message); 
       } 
      } 

     }   
    }  
+0

...私はどのようにシステムを減速せずに軌道をプロットすることは、この問題に対する解決策を提案することはできますか? C#にはシリアルポートがありません。 –

答えて

1

..

アプリケーションを実行し続けている、私は今、軌道

if (k == 14) 
{ 
    try 
    { 

     curr_x = (pictureBox2.Width/2) + (int)((engval[13] * (pictureBox2.Width))/map_width); 
     curr_y = (pictureBox2.Height/2) - (int)((engval[14] * (pictureBox2.Height))/map_height); 
     PointF p1 = new Point(curr_x, curr_y); 
     if (_gPath != null && _gPath.PointCount > 0) 
      p1 = _gPath.PathPoints[_gPath.PathPoints.Length - 1]; 
     PointF p2 = new Point(curr_x, curr_y); 
     _gPath.AddLine(p1, p2); 
     pictureBox2.Invalidate(); 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
    } 
} 

をプロットするためのグラフのパスを使用していますが、それはグラフの点の多くを収集しますしたがって、この膨大な数のポイントをプロットすることは、リソースを消費しています。

誰もがあなたが「C#シリアルポート」をどういう意味ですか

4

私は広範囲に定期的にそれ自体でSERIALPORTクラスの使用は、高いCPU負荷を生成しないことを、シリアルポートに接続されたデバイスで動作し、あなたを保証することがあります。

FIRST私はPROFILEアプリケーションにあなたをお勧めします。 a bunch of .NET用のプロファイラー

の後にのみプロファイリングSerialPortの読み取りとデータ処理を切り離すことをお勧めします。プロデューサーのコンシューマーパターンを使用します。 SerialPortからのデータをキューに入れ、他のスレッドから消費する。

それ私は私のプロジェクトの1

private void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e) 
    { 
     lock (SyncObject) 
     { 
      if (!_serialPort.IsOpen) return; 

      try 
      {      
       int toread = _serialPort.BytesToRead; 
       byte[] bytes = new byte[toread]; 
       _serialPort.Read(bytes, 0, toread); 

       ProducerAddBytes(bytes); 
      } 
      catch (TimeOutException) 
      { 
       //logic 
      } 
     } 
    } 

P.S.にSerialPortDataReceived機能に持っているものしかし、最初にプロフィール!私は上記のコードで問題だったものだ

+0

+1は、消費者の生産的アプローチを提案しています。 DataReceivedイベントはIO Completionスレッドから来ているので、データ処理を行い、そこでメソッド呼び出しを行うのは大きな間違いです。 – ogggre

+0

シリアルポートに問題はなかったとおっしゃったように荘厳に感謝しています。 – tspshikari