2017-03-23 11 views
1

私はマイクロプロセッサとC#フォームアプリケーションの間でシリアル通信をしようとしています。C#SerialPortリスニングポート

問題は、マイクロプロセッサから来るデータが2秒または5秒または10秒に来る可能性があるということです。私は特定の時間がないことを意味し、私はポートを聞いて、それが来るまでそれが来るまでデータを待つ2秒で来る場合は、データを取得したいと思います。

私はserialport.readline()でこれを試みました。しかし、フォームはreadlineブロック中にハングアップするので、私はバックグラウンドワーカーとやりとりをしました。

私が言っていることは、データの時間が来ている間、ポートを聞くことについてのいくつかの手がかりを教えてください。

は、あなたがデータ非同期を取得するためにSerialPort.DataReceived Eventを使用することができます(英語のため申し訳ありません、それは十分ではありません)お時間を

+0

:あなたは、あなたのコマンドを送信していた順番なので、後であなたが対応するメッセージを取り出して、配列内の400個のエントリを取得するためにSplitを使用することができますを知っていますか? –

+0

新たにstackoverflowに追加しよう – oakar

+0

フォームクローズイベントの中で、おそらくシリアルポートで 'Close()'を呼び出すこともできます。 'BackgroundWorker'を使用している場合、読み込み呼び出しのブロックを解除する必要がありますか? – nicholas

答えて

1

、ありがとうございました。 SerialPortクラスのインスタンスを作成した後、SerialPortにイベントハンドラを追加できます。イベントハンドラは、データが受信された場合に呼び出されます。

mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); 

ハンドラの内部では、入力バッファからデータを読み取り、必要な処理を実行できます。

private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) 
{ 
    SerialPort sp = (SerialPort)sender; 
    string indata = sp.ReadExisting(); 
    //Do what ever you want with the data 
} 

これは、アプリケーションをブロックせずに実行する不規則な時間ステップでデータを取得する非常に一般的なソリューションです。

+0

しかし、私はシリアルポートに私はデータとデータstartswithの間のスペースを持つ400のデータを取得する "A"を書くと、例えば、1つだけのデータを取得しない! "\ n"で終わるので、配列を使用しています。もしあなたが書いたように、配列はrelaibleではないと言います。 – oakar

+0

例を投稿できますか? – Fruchtzwerg

+0

@oakar文字列をスペースで区切って400要素の文字列[]を取得 –

1

DataReceivedイベントを使用できます。新しいデータがあなたのポートに到着するたびに解雇されます。あなたはこのようにそれを登録する必要があります。イベントハンドラで

SerialPort port = new SerialPort(/*your specification*/); 
port.DataReceived += Port_DataReceived; 

あなたがして、受信データを読み出します

private void Port_DataReceived(object sender, SerialDataReceivedEventArgs e) 
{ 
    SerialPort port = sender as SerialPort; 

    if (port != null) 
    { 
     var incoming_message = port.ReadExisting(); 
    } 
} 

今、あなただけのポートを開く必要があり、それが自動的に待機します。注意!入ってくるデータはメインスレッドとは異なるスレッドに到達します。

var incoming_message = port.ReadLine(); 

それともあなたは試みることができる:あなたが表示するために、フォームのコントロールを使用したいのであれば、あなたがReadLineメソッドを使用して試みることができるあなたのデータは\nで終わりにマークされている場合BeginInvoke

を使用する必要がありますReadTo

var incoming_message = port.ReadTo("\n"); 

EDIT:

このような長い時間がある場合は、バッチで読む必要があります。また、それをwhileループで処理しようとすることもできます。

private void Port_DataReceived(object sender, SerialDataReceivedEventArgs e) 
{ 
    SerialPort port = sender as SerialPort; 

    string message = ""; 
    if (port != null) 
    { 

     while(port.BytesToRead > 0) 
     { 
      message += port.ReadExisting(); 
      System.Threading.Thread.Sleep(500); // give the device time to send data 
     } 
    } 
} 

EDIT 2:

あなたがデータを保存したい場合は、イベントハンドラのList<string>外を宣言し、それが完全に読み込まれたときに文字列を追加します。

List<string> dataStorage = new List<string>(); 


private void Port_DataReceived(object sender, SerialDataReceivedEventArgs e) 
{ 
    SerialPort port = sender as SerialPort; 

    string message = ""; 
    if (port != null) 
    { 

     while(port.BytesToRead > 0) 
     { 
      message += port.ReadExisting(); 
      System.Threading.Thread.Sleep(500); // give the device time to send data 
     } 
     // add now the entire read string to the list 
     dataStorage(message); 
    } 
} 

イベントハンドラを使用すると、1つのリスト内全体受信したメッセージを集めるだけでAまたはBを送っているかどうかわからないので。あなたが任意のコードサンプルを持っていますかあなたは私たちを見ることができます

string [] A_array_data = dataStorage[0].Split(" "); 
+0

私はこれを使用しましたが、Read.existing()はデータをすべて待っていません。たとえばシリアルポートに書き込むときに、データとデータの間にスペースを入れて400個のデータを取得します。あなたは配列がrelaible(私は分割を使用していない)と言ったように書く場合 – oakar

+0

@oakarデバイスが400バイトを送信するのにどれくらい時間がかかりますか?それはバイトですか?または400文字? –

+0

'ReadLine()'を試しましたか? –

関連する問題