2011-03-21 16 views
0

datarecievedベースのイベントハンドラを実装しようとしていますが、ポートからデータを受け取ることはできますが、イベントを実行するのが難しいと思います。私はReadLineとReadExistingの両方を試しました。私はシリアル通信で多くの作業を行っている、と私はそれがしたいようDataReceivedが働くことがないおかげで、datareceivedイベントハンドラをシリアルC#

private void Form1_Load(object sender, EventArgs e) 
     { 
       // graphing stuff 
      portname = "COM1"; 
      parity = Parity.None; 
      BaudRate = 115200; 
      stopbits = StopBits.One; 
      databits = 8; 
      port = new System.IO.Ports.SerialPort(portname); 
      port.Parity = parity; 
      port.BaudRate = BaudRate; 
      port.StopBits = stopbits; 
      port.DataBits = databits; 
      port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived); 
      port.Open(); 
      count = 0; 
      } 


    void port_DataReceived(object sender, SerialDataReceivedEventArgs e) 
    { 
     try 
     { 
     line = port.ReadLine(); 
     count++; 
     this.BeginInvoke(new LineReceivedEvent(LineReceived),line); 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.Message); 
      } 
    } 

    private delegate void LineReceivedEvent(string text); 

    private void LineReceived(string text) 
    { 

     if (zedGraphControl1.GraphPane.CurveList.Count <= 0) 
      return; 
     LineItem curve = zedGraphControl1.GraphPane.CurveList[0] as LineItem; 
     if (curve == null) 
      return; 
     IPointListEdit list = curve.Points as IPointListEdit; 
     double value = double.Parse(text); 
     list.Add(count, value); 
     // graphing stuff 
    } 

// graphing stuff 
} 
+0

ボーレートを低く抑えてください。一度に1つの番号を呼び出しています。これは、UIスレッドがペイントを停止させる原因となる多くの呼び出しです。あなたのユーザーは1秒間に約20回のアップデートしか見ることができません。問題を解決するためのバッファ。 –

答えて

1

..私のコードにコメントしてください。 SerialPortにはReceivedBytesThresholdと呼ばれるプロパティがあります。これはイベントが発生したときに変更されるはずですが、私はそれを打ち負かしてしまいました。このイベントで何人かのグーグル・グーグルをしてください。何千もの問題が報告されています。イベントは時々動作することがありますが、私はミッションクリティカルな操作のためにそれに依存しません。

行末を探している場合、私が見つけたほうがよい方法は、利用可能な場合にバイトをバッファに連続的に読み込み、バッファ上でLineReceivedメソッドを呼び出すだけです。行末に出会う。これを独自のスレッドに入れてください。ループの内側にいくつかThread.Sleep()を追加して引き継がないようにします。

シリアルストリームに瞬時に反応しない場合は、スレッドタイマーで秒または半秒ごとに実行します。タイマーの各ティックは、すべての既存のバイトをバッファーに読み込み、行終了に遭遇するたびにLineReceivedを呼び出します。

+0

DataReceivedでどんな問題がありましたか?それは私のためにうまく働いた(私はReceivedBytesThreshold = 1だったと思う) – Justin

+0

時々、私は全く問題がない。それ以外の時は、必要なときに発砲することを単に拒否します。データが非常に間欠的な場合(そしてボーレートが遅い場合)、私は運が良くなる傾向があります。私は次のデータ群が到着する前にイベントハンドラが終了していないということがあると思います。しかし、私はそれを手動で行うと平均的に私にとって良い結果が得られます。 – drharris

+0

Ok ..私はちょうどいくつかの問題を修正したが、期待どおりに動作していないようだ。(デリゲートの私の宣言は私が呼んだ後であった!)データのいくつかはdoubleによって認識されなかった。しかし、私は何が送られているのは改行で二重であるということを他の人にも気を配っています!とにかく、私はfloat.tryparseした、それは救済が、しかし、私はそれらのすべてを取得していないことを知っているように働いているようだ..この仕事は、それが完了したときにいくらか批判的なので、私はdrharrisが示唆.. – Programmer

0

私はまた、私たちの製品の1つで大きな成功を収めたDataReceivedイベントを使用しています。私が実装しているプロトコルでは、最小パケットサイズが6バイトであることを要求しています。

私は、孤立したデータを残しておき、次に不完全な読み込みパケットや不正な形式のパケットがあった場合にイベントが発生したときに再構築します。私は実際にこの実装にはほとんど問題がありませんでした。私はイベントハンドラでロックすることをお勧めします。そうすれば、シリアルポート上で競争に終わることはありませんが、それは必要ないかもしれません。

関連する問題