トップ回答者
SerialPortコンポーネントを使用してACK待ちするには

質問
-
回答
-
新たに監視スレッドを立ち上げる必要は無いと思います。
SerialPortの受信イベントは別スレッドで発生されるものですが、実装する場合は、通常のイベント処理と同じような実装になると思います。
※余談ですが、画面系の操作は、現在バインドされているスレッドからのみ有効なので、Invokeメソッドでメインスレッドのdelegateをコールする必要があります。
問題は、DataReceivedイベントがデータが届くたびにバンバン発生することです。
そのため、現在受信したデータ長を、チェックして、規定のデータ長であれば、受信するという方式をとる必要があると思います。
あと、「Monitorでwaitし、受信したら、Pulse」と書かれてますが、
この通りに実装すると、メインスレッドが待ち状態になり、固まってしまうのでは?
なので、DataReceivedイベントのタイミングではなく、
決められたTimerの時間間隔でSerialPortのデータを読み取る、でもいいと思います。
この方法ですと、「命令を送ってから、500msec以内にACKを受け取る」といった仕様があったとしたら、
①命令を送信する
②タイマーを開始する
③500msec後にタイマイベントが発生するので、シリアルポートのデータを取得
④受信データのチェックをしてNGなら通信エラー
とかどうでしょう?
すべての返信
-
新たに監視スレッドを立ち上げる必要は無いと思います。
SerialPortの受信イベントは別スレッドで発生されるものですが、実装する場合は、通常のイベント処理と同じような実装になると思います。
※余談ですが、画面系の操作は、現在バインドされているスレッドからのみ有効なので、Invokeメソッドでメインスレッドのdelegateをコールする必要があります。
問題は、DataReceivedイベントがデータが届くたびにバンバン発生することです。
そのため、現在受信したデータ長を、チェックして、規定のデータ長であれば、受信するという方式をとる必要があると思います。
あと、「Monitorでwaitし、受信したら、Pulse」と書かれてますが、
この通りに実装すると、メインスレッドが待ち状態になり、固まってしまうのでは?
なので、DataReceivedイベントのタイミングではなく、
決められたTimerの時間間隔でSerialPortのデータを読み取る、でもいいと思います。
この方法ですと、「命令を送ってから、500msec以内にACKを受け取る」といった仕様があったとしたら、
①命令を送信する
②タイマーを開始する
③500msec後にタイマイベントが発生するので、シリアルポートのデータを取得
④受信データのチェックをしてNGなら通信エラー
とかどうでしょう?
-
-
シリアルポート関係は調べてもなかなか詳しく書いたところが無くて苦労しますよね。。。
今更C++/CLIの話で適用できるかはわかりませんが、
Data_Recievedイベント中にBeginInvoke()で別スレッドを呼び出し、
そこで処理をするようにするのが良いかと思います。
___________________________
private:
System::Void deligate DLGTHoge(String^ hogestring);
System::Void Hoge(String^ hogestring){
// 実際のデータをこちゃこちゃいじる処理
//serialPort->ReadExisting();は必ずしも送信されたデータを全て受信するとは限らないので、
//(メソッド呼び出し時にバッファに存在するデータのみ全て取得するため)
//グローバルな変数に受信データを+=したりするといいかもしれません。
}
private: System::Void Data_Recieved(){
String^ StrRecieveString;
DLGThoge^ DRHOGE = gcnew(this, &namespace::class::method);
StrRecieveString = this->serialPort->ReadExisting(); //とりあえず全部取得
this->BeginInvoke(DRHOGE, StrRecieveString);//データの扱いは他のスレッドに任せる。
}
※適当に手打ちしたので、コピペして動くかは知りません。
______________________________
こんな感じで処理したほうがタイマー待ちを行うよりスマートだと思います。
ちなみにC++/CLIだとInvoke()を使用して立ち上げると、Application::Exit();
がうまく働きません。なのでBeginInvoke()ですが、他の言語ではどうか知りません。
これならば、データの受信が無いときはデータ受信待ち処理を
メインスレッド内でやる必要が無いので効率がよくなると思いますが、
いかがでしょうか?